从函数C ++返回一个对象

时间:2013-03-26 21:15:09

标签: c++ function computer-science

假设我有一个变量指向我制作的对象。对于这个例子,假设我有一个代表卡片的对象,它有2个成员 - 排名和适合。

接下来,让我说我初始化了我制作的对象结构,所以我现在有一个具有等级和套装的卡片对象。

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

Card* playerCard = foo()

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

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

感谢您的帮助!

4 个答案:

答案 0 :(得分: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衍生物。

答案 1 :(得分: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和移动语义,它实际上最终会变慢),所以除了运行时多态(即工厂方法)之外,没有什么理由这样做。

答案 2 :(得分:0)

如果要返回指针,可以使用动态内存分配,否则在执行foo后指针将指向任何内容(参见Dangling pointers):

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

上述代码的另一个版本将使用标准库中的std::unique_ptr来向您的代码的客户端程序员明确表示您正在返回动态分配的指针。它是一个智能指针,因此它会在其作用域的末尾自动解除分配(这不是函数的末尾,因为它被复制到调用块)。

否则,如果您的对象/结构复制起来并不昂贵,您可以按值返回,从而导致复制:

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

答案 3 :(得分:0)

如果函数foo()返回一个指向已经创建的Card对象的指针,那么为它指定一个Card指针应该可以正常工作。重要的是要记住,你有效地传递了相同的卡,但不是副本或任何东西。