7

假设我有以下代码:

class some_class{};

some_class some_function()
{
    return some_class();
}

这似乎工作得很好,并且省去了我必须声明一个变量来创建一个返回值的麻烦。但我认为我从未在任何类型的教程或参考资料中看到过这一点。这是特定于编译器的东西(Visual C++)吗?或者这是做错了什么?

4

7 回答 7

16

不,这是完全有效的。这也将更有效,因为编译器实际上能够优化掉临时的。

于 2008-09-18T20:26:34.860 回答
5

从函数调用返回对象是“工厂”设计模式,并且被广泛使用。

但是,无论是返回对象还是指向对象的指针,您都需要小心。前者将向您介绍复制构造函数/赋值运算符,这可能会很痛苦。

于 2008-09-18T20:32:41.680 回答
2

它是有效的,但性能可能并不理想,具体取决于它的调用方式。

例如:

A a;
a = fn();

A a = fn();

不一样。

在第一种情况下,调用默认构造函数,然后在需要构造临时变量的 a 上调​​用赋值运算符。

在第二种情况下,使用了复制构造函数。

一个足够聪明的编译器会计算出哪些优化是可能的。但是,如果复制构造函数是用户提供的,那么我看不到编译器如何优化临时变量。它必须调用复制构造函数,并且为此它必须有另一个实例。

于 2008-09-18T20:38:02.337 回答
2

Rob Walker 的示例之间的区别称为返回值优化 (RVO),如果您想搜索它。

顺便说一句,如果您想确保您的对象以最有效的方式返回,请使用 shared_ptr 在堆上创建对象(即通过 new)并返回 shared_ptr。指针被返回并且引用计数正确。

于 2008-09-18T20:47:01.817 回答
1

这是完全合理的 C++。

于 2008-09-18T20:26:37.497 回答
1

这是完全合法的 C++,任何编译器都应该接受它。是什么让您认为它可能做错了什么?

于 2008-09-18T20:27:45.543 回答
1

如果您的课程非常轻量级,那是最好的方法——我的意思是复制它并不是很昂贵。

但是,该方法的一个副作用是它确实倾向于使其更有可能创建临时对象,尽管这可能取决于编译器对事物的优化程度。

对于要确保不复制的更重量级的类(例如,一个大的位图图像),最好将类似的东西作为参考参数传递,然后将其填充,以确保绝对确保不会创建任何临时对象。

总体而言,简化语法并使事情变得更直接可能会产生在表达式中创建更多临时对象的副作用,这正是您在为更重量级的对象设计接口时应该牢记的事情。

于 2008-09-18T20:43:25.600 回答