假设我有以下代码:
class some_class{};
some_class some_function()
{
return some_class();
}
这看起来效果很好,并且省去了为了生成返回值而必须声明变量的麻烦。但我认为我从未在任何教程或参考中看到过这一点。这是编译器特定的东西(visual C ++)吗?或者这是做错了什么?
答案 0 :(得分:16)
这不是完全有效的。这也将更有效,因为编译器实际上能够优化临时。
答案 1 :(得分:5)
从函数调用返回对象是“工厂”设计模式,并被广泛使用。
但是,无论是返回对象还是指向对象的指针,都要小心。前者将介绍复制构造函数/赋值运算符,这可能很痛苦。
答案 2 :(得分:2)
它是有效的,但性能可能并不理想,具体取决于它的调用方式。
例如:
A a;
a = fn();
和
A a = fn();
不一样。
在第一种情况下,调用默认构造函数,然后调用赋值运算符,这需要构造一个临时变量。
在第二种情况下,使用复制构造函数。
足够聪明的编译器将确定可能的优化。但是,如果复制构造函数是用户提供的,那么我不会看到编译器如何优化临时变量。它必须调用复制构造函数,为此,它必须有另一个实例。
答案 3 :(得分:2)
Rob Walker的例子之间的差异叫做返回值优化(RVO),如果你想谷歌的话。
顺便提一下,如果您想确保以最有效的方式返回对象,请使用shared_ptr在堆上创建对象(即通过new)并返回shared_ptr。指针返回并且引用计数正确。
答案 4 :(得分:1)
这是完全合理的C ++。
答案 5 :(得分:1)
这是完全合法的C ++,任何编译器都应该接受它。是什么让你觉得它可能做错了什么?
答案 6 :(得分:1)
如果您的课程非常轻巧,那么这是最好的方法 - 我的意思是制作副本并不是非常昂贵。
该方法的一个副作用是,它确实倾向于使其更有可能创建临时对象,尽管这可能取决于编译器如何优化事物。
对于你想要确保没有被复制的更重量级的类(例如一个大的位图图像),那么最好将这样的东西作为参考参数传递然后填入,只是为了制作绝对确保不会创建任何临时对象。
总的来说,简化语法并使事情更直接转换可能会产生在表达式中创建更多临时对象的副作用,这只是在为更重量级的对象设计接口时应该记住的事情。