2013-03-26 144 views
-1

可以说我有一个变量指向我创建的对象。对于这个例子,可以说我有一个代表一张卡片的对象,该卡片有两个成员 - 排名和套装。从函数返回一个对象C++

接下来,可以说我初始化了我制作的物体结构,所以我现在有了一个拥有等级和套装的卡物。

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

Card* playerCard = foo() 

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

基本上我想我的功能来生成卡,并且playerCard应该等于生成的卡。我不知道返回一个对象是否是最直接的解决方案,这就是为什么我也问是否有其他解决方案。

感谢您的帮助!

+4

我不确定你的所有要求,但我认为返回'Card',而不是'Card *',应该没问题。 – juanchopanza 2013-03-26 21:17:38

回答

7

我将逐渐从不良到好的方法。

首先,这是错误的方式做到这一点:

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

+0

+1。你今天不可阻挡;) – 2013-03-26 21:27:02

+0

“为什么不只是退还'卡'?”因为你可能想从'Card'继承,在这种情况下,你有很大的切片危险。 – 2013-03-26 21:31:27

+0

@MattPhillips当然,这就是我问的原因。 :D – 2013-03-26 21:32:19

0

,如果你想返回一个指针,您可以使用动态内存分配,否则你的指针会的foo执行后指向什么(见Dangling pointers):

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

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

否则,如果你的对象/结构也不是很贵复制,你可以通过值导致复制返回它提出:

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

该副本很可能会在第二个代码示例中消失,因此不应考虑复制的费用。 – juanchopanza 2013-03-26 21:24:57

+0

@juanchopanza,它真的取决于具体编译器的实现,不是吗? – Shoe 2013-03-26 21:26:12

+0

是的,它的确如此,但是很难找到那些近期没有这样做的人。 – juanchopanza 2013-03-26 21:27:15

0

如果函数foo()返回一个指向一个卡对象是已创建,分配一个卡指针,它应该工作得很好。重要的是要记住,你有效地通过它相同的卡虽然,不是副本或任何东西。

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