【发布时间】:2017-02-20 15:59:45
【问题描述】:
这里是 C++ 新手!有一个类Individual 分配了很多内存,这样我们就想避免复制。让mother 和father 成为两个Individuals。我希望他们使用reproduce 方法复制另一个Individual,称为baby。
直观地说,我会用默认构造函数初始化baby,将它作为参数传递给reproduce,然后返回引用(尽管我认为没有必要返回引用)。这是执行此操作的代码
class Individual
{
public:
void reproduce (const Individual& father, Individual& baby)
{
// Set all attributes of baby
}
private:
// Plenty of variables
}
int main()
{
// Do Stuff
Individual mother(arg1,arg2,arg3);
Individual father(arg1,arg2,arg3);
// Do stuff
Individual baby;
mother.reproduce(father,baby);
}
这算是好的做法吗?
另一种方法是直接在方法reproduce 中初始化baby 并返回一个引用,但我预测baby 将在reproduce 的调用结束时被销毁。
class Individual
{
public:
Individual& reproduce (const Individual& father)
{
Individual baby;
// Set all attributes of baby
return baby
}
private:
// Plenty of variables
}
int main()
{
// Do Stuff
Individual mother(arg1,arg2,arg3);
Individual father(arg1,arg2,arg3);
// Do stuff
auto baby = mother.reproduce(father);
}
也可以使用外部函数,但我看不出它可以代表什么优势。
【问题讨论】:
-
关于第二种情况,返回对临时的引用是未定义的行为。
-
为什么不直接返回一个值呢? UB 代表未定义的行为。引用所指的东西将超出范围并且在控制权返回给调用者后不存在,因此当他们使用它时,他们会得到 UB。
-
“我们希望尽可能避免复制”——您是否测量过这是一个瓶颈?不要以性能的名义不必要地使您的代码复杂化,除非您确定优化会给您带来可衡量的改进。在那之前,只需构造并返回一个临时的
baby并返回它。 -
我会按值返回
baby。与传入外部创建的婴儿相比,它是一种更好的现实模型。您可以使用 move 构造函数/赋值来使返回值便宜。 -
请注意,从方法中按值返回对象通常不需要复制该对象,因为大多数 C++ 编译器通常实现返回值优化:en.wikipedia.org/wiki/Return_value_optimization
标签: c++ performance class methods