返回默认构造值有什么问题吗?

7
假设我有以下代码:
class some_class{};

some_class some_function()
{
    return some_class();
}

这似乎很好用,可以省去我声明变量来返回值的麻烦。但是我从未在任何教程或参考资料中看到过这种写法。这是编译器特定的事情(Visual C++)吗?还是做了什么不对的事情?

7个回答

16

不,这是完全有效的。而且这样会更加高效,因为编译器实际上可以优化掉临时变量。


实际上,现代编译器经常能够优化掉返回的命名变量。 - Nemanja Trifunovic

5

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

但是,您需要小心是返回对象还是对象指针。前者会使您接触到复制构造函数/赋值运算符,这可能很麻烦。


2

这是合法的,但是性能可能取决于它被调用的方式而不是理想的。

例如:

A a;
a = fn();

并且。
A a = fn();

两者并不相同。

在第一种情况下会调用默认构造函数,然后对a进行赋值操作,这需要构造一个临时变量。

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

一个足够智能的编译器将会计算出可能的优化。但是,如果复制构造函数是用户提供的,则我不认为编译器可以优化掉临时变量。它必须调用复制构造函数,而要做到这一点,它必须有另一个实例。


1
标准明确允许编译器省略复制构造函数。 - Daniel James

2

如果你想要搜索一下,罗布·沃克(Rob Walker)的例子所涉及的差异被称为返回值优化(RVO)。

顺便提一下,如果你希望以最高效的方式返回对象,请使用 shared_ptr 在堆上创建对象(即通过 new),并返回一个 shared_ptr。指针将被返回并正确引用计数。


1
一般来说,RVO比使用shared_ptr更有效率,因为对象会直接在堆上创建。此外,shared_ptr需要创建一个额外的对象来存储计数。 - Daniel James

1

这是非常合理的 C++。


1

这是完全合法的C++代码,任何编译器都应该接受它。你为什么认为它可能会做错事呢?


只是在我有限的C++经验中,我从未真正看到它被用过。 - Jason Baker
好的。如果没有使用临时变量的理由,那么肯定可以直接使用它! - Greg Hewgill

1

如果你的类非常轻量级,也就是说复制它不会很耗费资源的话,那么这是最好的方法。

然而,这种方法有一个副作用,就是很可能会创建临时对象,尽管这取决于编译器优化的效果如何。

对于更重量级的类(例如大型位图图像),你想确保不被复制,那么将这些东西作为引用参数传递并填充是一个好主意,这样可以绝对确保不会创建任何临时对象。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接