C++ C++;按值返回

C++ C++;按值返回,c++,function,copy-constructor,C++,Function,Copy Constructor,从下面的代码中,我希望CA类能够调用下面的代码 构造函数创建要由函数foo返回的临时对象 复制构造函数以创建要传递到主菜单中变量a的变量 另一个复制构造函数,它将根据函数返回的值创建变量 为什么不是这样?我得到的结果是公正的 A 在我期待的时候 ABB 因此,只调用构造函数。编译器是在幕后优化还是错过了一些C++概念? class CA{ public: CA(){ std::cout << "A"; } CA( const CA& ){ std::cout

从下面的代码中,我希望CA类能够调用下面的代码

  • 构造函数创建要由函数
    foo返回的临时对象
  • 复制构造函数以创建要传递到主菜单中变量
    a
    的变量
  • 另一个复制构造函数,它将根据函数返回的值创建
    变量
  • 为什么不是这样?我得到的结果是公正的

    A
    
    在我期待的时候

    ABB
    
    因此,只调用构造函数。编译器是在幕后优化还是错过了一些C++概念?
    class CA{
    public:
       CA(){ std::cout << "A"; }
       CA( const CA& ){ std::cout << "B"; }
       CA& operator=(const CA& ){ std::cout << "C";return *this; }
    };
    
    CA foo(){
          return CA();
    }
    
    int main(){
     CA a = foo();    
    }
    
    CA类{
    公众:
    CA(){std::cout
    

    编译器是在幕后优化一些东西还是我错过了一些C++概念?

    class CA{
    public:
       CA(){ std::cout << "A"; }
       CA( const CA& ){ std::cout << "B"; }
       CA& operator=(const CA& ){ std::cout << "C";return *this; }
    };
    
    CA foo(){
          return CA();
    }
    
    int main(){
     CA a = foo();    
    }
    
    注意!这叫做复制省略。在谷歌上查RVO和NRVO。你还应该查三的规则

    复制删除是编译器允许执行的唯一优化,它影响可观察行为。因此,不应该在复制构造函数中放置重要逻辑。

    < P>在C++中至少有两种“优化”。
    • 第一类是语言规范明确引入的特定优化

    • 第二类是编译器在“似乎”规则下所做的所有疯狂和不可预测的优化(即,只要程序的可观察行为保持不变,编译器就完全可以做任何事情)

    (有人可能会说,只有第二种优化才是真正的优化。)

    您在这里看到的是第一种优化。在执行多步骤复制操作时,语言规范始终明确允许编译器消除中间临时副本

    此外,C++03和更高版本的语言规范更进一步:它们明确允许编译器执行“命名返回值优化”(NRVO),这实际上消除了命名(非临时)对象

    两者都可以减少程序中的复制操作数

    <> P>这种C++复制复制优化是允许的,即使它们改变了程序的可观察行为,即第一类的优化有时会违反第二类的限制。在这种情况下,即使将I/O操作插入到复制构造函数中,编译器仍然允许被删除。调用该构造函数

    您发布的代码不需要NRVO。一个好的C++98编译器应该能够生成您观察到的结果。如果您想查看您的编译器在这种情况下是否执行NRVO,您可能希望尝试此方法

    CA foo(){
      Ca ca;
      return ca;
    }
    

    如果你仔细想想,ctor是唯一需要运行的东西