2008-09-18 71 views
7

假设我有以下代码:返回默认构造值有什么问题吗?

class some_class{}; 

some_class some_function() 
{ 
    return some_class(); 
} 

这似乎是工作得很好,节省了我要声明一个变量只是做一回值的麻烦。但我认为我从来没有在任何教程或参考资料中看到过这一点。这是一个特定于编译器的东西(Visual C++)吗?或者这是否做错了什么?

回答

16

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

+0

实际上,现代编译器通常能够优化掉一个返回的命名变量 – 2008-09-18 20:32:13

1

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

+0

这只是我从来没有真正看到它在我有限的C++经验中的任何地方使用。 – 2008-09-18 20:28:49

+0

够公平的。绝对使用它,如果没有理由使用临时变量,那么你不必! – 2008-09-18 20:29:38

5

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

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

2

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

例如:

A a; 
a = fn(); 

A a = fn(); 

是不一样的。

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

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

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

+1

该标准明确允许编译器删除拷贝构造函数。 – 2008-09-19 18:42:30

1

这是最好的方式来做到这一点,如果你的课程非常轻量级 - 我的意思是它不是很昂贵的复制它。

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

对于你想确保不会被复制的更重量级的类(比如说一个大的位图图像),那么把一个像这样的东西作为参考参数传递是一个好主意,确保不会有任何临时对象被创建。

总的来说,简化语法和使事情变得更加直接的事情可能会在表达式中创建更多临时对象的副作用,只是在设计更重量级对象的接口时应该记住的事情。

2

Rob Walker的示例之间的区别称为返回值优化(RVO),如果您想要Google的话。顺便说一下,如果你想确保你的对象以最有效的方式得到返回,那么使用shared_ptr在堆上创建对象(即通过new),并返回一个shared_ptr。指针返回并且引用计数正确。