从函数返回一个对象

Returning an object from a function C++

本文关键字:一个对象 返回 函数      更新时间:2023-10-16

假设我有一个指向我创建的对象的变量。对于这个例子,假设我有一个对象表示一张牌,它有两个成员——秩和花色。

接下来,假设我初始化了刚才创建的对象结构,现在我有了一个包含秩和花色的card对象。

我的问题是,如果我想要一个函数来返回我创建的这个card对象:我想这样做:

Card* playerCard = foo()

我知道playerCard是指向一个卡对象,所以这是否意味着foo()也必须返回一个卡对象?这个问题还有别的解决办法吗?

基本上,我希望我的函数生成卡片,playerCard应该等于生成的卡片。我不知道返回一个对象是否是解决问题最直接的方法,这就是为什么我还要问是否有其他解决方案。

谢谢你的帮助!

我将逐步从坏方法到好方法。

首先,这是错误的做法:

Card* foo() {
  Card c;
  return &c;
}

绝对不要那样做。Cardc将在foo结束时被销毁,因此您返回的指针将指向一个无效对象。

可以这样做:

Card* foo() {
  return new Card();
}

new Card()创建的卡具有动态存储时间,因此在foo结束时不会被销毁。因此返回的指针仍然指向那张牌。这样就可以安全地使用指针了。

然而,这有另一个缺点。调用foo的人不清楚,但他们现在负责在返回的指针上执行delete,以确保没有内存泄漏。相反,最好使用智能指针明确地将所有权传递给调用者:

std::unique_ptr<Card> foo() {
  return std::unique_ptr<Card>(new Card());
}

然而,如果你根本不需要动态分配,那就更好了。为什么不返回Card,让它从函数中复制出来?你可以这样做:

Card foo() {
  return Card();
}

然后不给指针赋值,而是像这样调用函数:

Card c = foo();

当然,这取决于您的需求允许这样做。如果您想以多态方式使用Card*,则需要使用指针方法之一。否则,您最终将切割您的Card衍生品。

你返回的是一个指向对象的指针,而不是一个对象。

我不确定你的问题到底是什么,所以我给你一个完整的例子:

struct card {int rank; int suit};
card make_a_card() {
   return card{10,3};
}
int main() {
    card a_card = make_a_card();
    // a_card == card{10,3}
}

很少需要从函数返回原始指针。对于速度来说,这并不是必须的(事实上,由于RVO和move语义,它实际上最终会变得更慢),所以除了运行时多态性(即对于工厂方法)之外,几乎没有理由这样做。

如果函数foo()返回一个指向已经创建的Card对象的指针,那么给它分配一个Card指针应该可以正常工作。重要的是要记住,您实际上传递给它的是与相同的卡片,而不是副本或任何东西。

如果你想返回一个指针,你可以使用动态内存分配,否则你的指针在执行foo后将不指向任何东西(参见悬空指针):

Card* foo() {
    Card* ret = new Card(...);
    ...
    return ret;
}

上述代码的另一个版本将使用标准库中的std::unique_ptr,以使代码的客户程序员清楚地知道您正在返回一个动态分配的指针。它是一个智能指针,因此它会在其作用域结束时自动释放自身(而不是在函数结束时,因为它被复制到调用块中)。

否则,如果你的对象/结构体复制成本不高,你可以按值返回它,从而进行复制:

Card foo() {
    Card ret(...);
    ...
    return ret;
}