-1

假设我有一个变量指向我制作的对象。对于这个例子,假设我有一个代表一张卡片的对象,它有 2 个成员 - 等级和花色。

接下来,假设我初始化了我创建的对象结构,所以我现在有一个带有等级和花色的卡片对象。

我的问题是,如果我想要一个返回我创建的卡片对象的函数怎么办:我想做这样的事情:

Card* playerCard = foo()

我知道 playerCard 指向一个卡片对象,那么这是否意味着 foo() 也必须返回一个卡片对象?有没有另一种方法来解决这个问题?

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

谢谢您的帮助!

4

4 回答 4

7

我将逐步从坏方法变为好方法。

首先,这是错误的做法:

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

绝对不要那样做。将Card c在结束时被销毁,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衍生品。

于 2013-03-26T21:19:17.143 回答
1

您正在返回指向那里的对象的指针,而不是对象。

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

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 和移动语义,它实际上最终可能会变慢),因此除了运行时多态性(即对于工厂方法)之外,几乎没有理由这样做。

于 2013-03-26T21:19:28.807 回答
0

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

于 2013-03-26T21:19:14.833 回答
0

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

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

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

否则,如果您的对象/结构复制成本不高,您可以按值返回它,从而导致复制:

Card foo() {
    Card ret(...);
    ...
    return ret;
}
于 2013-03-26T21:18:33.507 回答