【问题标题】:Is there anything wrong with returning default constructed values?返回默认构造值有什么问题吗?
【发布时间】:2010-09-10 22:09:18
【问题描述】:

假设我有以下代码:

class some_class{};

some_class some_function()
{
    return some_class();
}

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

【问题讨论】:

    标签: c++ oop visual-c++ constructor


    【解决方案1】:

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

    【讨论】:

    • 事实上,现代编译器通常能够优化掉返回的命名变量
    【解决方案2】:

    这是完全合理的 C++。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 只是在我有限的 C++ 经验中,我从未真正看到它在任何地方使用过。
      • 很公平。绝对使用它,如果没有理由使用临时变量,那么你不必!
      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

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

        例如:

        A a;
        a = fn();
        

        A a = fn();
        

        不一样。

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

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

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

        【讨论】:

        • 标准明确允许编译器省略复制构造函数。
        【解决方案6】:

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

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

        对于您希望确保不被复制的更重量级的类(例如大的位图图像),最好将类似的东西作为参考参数传递,然后将其填充,只是为了使绝对确定不会创建任何临时对象。

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

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

          • 一般来说,RVO 比使用 shared_ptr 更有效,对象是在堆上就地创建的。此外,shared_ptr 必须创建一个额外的对象来存储计数。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-02-13
          • 2021-10-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多