在C ++中没有RVO创建的对象和复制ctors

时间:2011-05-16 19:52:50

标签: c++

我是C ++的新手。请考虑以下代码:

class foo 
{ 
 int f; 

 public: 
   foo(int f1=0) : f(f1) { 
   cout<<"In conversion ctor\n"; 
 } 

foo(const foo & rhs) : f(rhs.f) 
{ 
    cout<<" In copy ctor\n"; 
} 

 foo& operator=(const foo & that) 
{ 
    f=that.f; 
    cout<<"In = optor\n"; 
    return *this; 
} 

}; 

 foo rbv() 
  { 
    foo obj(9); 
    return obj;                        //named return by value [def. 1] 
  } 

   foo caller() 
   { 
      return rbv();              // return by value [def. 2] 
   } 

int main(void) 
{ 
   foo box=caller(); 
   return 0; 
 }
  1. RBV和NRBV的定义是否正确,如下所示 评论?
  2. 是否必须通过它定义可访问的副本ctor 在RVO期间没有调用?
  3. 没有RVO,在代码块中

       foo rbv() 
        { 
         foo obj(9); 
         return obj; 
        } 
    
        foo ret= rbv();
    
  4. 创建'ret'时,以下步骤是否正确

    (1)使用来自obj的copy ctor创建临时(比如说obj_temp),  堆栈对象'obj'被破坏,

    (2)ret是从obj_temp构造的复制,obj_temp后来被销毁;

    这意味着有三个对象,'obj','obj_temp'和'ret'以及两个复制ctors。

2 个答案:

答案 0 :(得分:5)

  

RBV和NRBV的定义是否正确,如评论中所示?

它们是RVO和NRVO(返回值优化和命名返回值优化)

  

是否必须定义可访问的副本ctor,尽管在RVO期间没有调用它?

这是强制性的,编译器必须验证构造函数是否可访问,如果不是,编译器必须触发错误并且无法编译。

  

没有RVO,在代码块中

foo rbv() { 
  foo obj(9); 
  return obj; 
} 
foo ret = rbv();

现在的代码需要执行以下操作:构造函数在int内部foo创建obj。将return语句中的构造复制到返回临时$tmp1,从临时位置复制呼叫位置ret的构造。现在,编译器可以通过在ret之上放置返回值(根据调用约定)来删除这两个副本,因此$tmp1ret是相同的内存位置,并且在同一个内存位置上构建obj,所以最后所有三个对象都可以是一个对象,不需要执行任何副本。

答案 1 :(得分:0)

  1. 看起来对我来说。
  2. 如果要复制对象,则必须定义可访问的复制构造函数。即使副本可以被优化掉。
  3. 这对我来说是正确的,尽管精确的排序可能是实现定义的。你必须