假设我有一个变量指向我制作的对象。对于这个例子,假设我有一个代表卡片的对象,它有2个成员 - 排名和适合。
接下来,让我说我初始化了我制作的对象结构,所以我现在有一个具有等级和套装的卡片对象。
我的问题是,如果我想要一个返回我创建的卡对象的函数,该怎么办: 我想做这样的事情:
Card* playerCard = foo()
我知道playerCard指向一个卡片对象,这是否意味着foo()还必须返回一个卡片对象?还有另一种解决这个问题的方法吗?
基本上我希望我的功能生成卡,而playerCard应该等于生成的卡。我不知道返回一个对象是否是解决问题最直接的方法,这就是为什么我也在询问是否有任何替代解决方案。
感谢您的帮助!
答案 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指针应该可以正常工作。重要的是要记住,你有效地传递了相同的卡,但不是副本或任何东西。