构造函数重载解析和编译

时间:2017-08-31 10:54:39

标签: c++11 constructor

具有3个构造函数的结构TB,下面的代码编译和复制构造函数 - "构造函数A"被叫两次。评论"构造函数C"导致编译问题。

这是什么原因?

为什么在构造函数B中取消注释const会影响编译结果?

这是否与覆盖默认的复制赋值运算符有关?

这里适用的解决规则是什么?

int doIgetHere = 0;

struct TA{
    int a;
};

struct TB{
    int b;
    //Constructor A
    TB(TA &ta){
        b = ta.a;
    }

    //Constructor B 
    TB(/*const*/ TB &tb){
        doIgetHere++;
        b = tb.b;
    }

    // Constructor C === removing this constructor cause compilation problem, why ?
    TB(TB && mtb){
        doIgetHere++;
        b = mtb.b;
    }
};

int main(){
    TA ta;     

    TB tb1(ta);  // using constructor A
    TB tb2 = ta; // using constructor A     

    std::cout<<doIgetHere<<"\n"; // result is 0, as expected
}

编译日志:

  

34:5:错误:没有可行的构造函数复制类型&#39; TB&#39;

    TB tb2 = ta; // using constructor A  

       ^     ~~  
     

18:2:注意:候选构造函数不可行:期望第一个参数的l值

    TB(/*const*/ TB &tb){  

    ^ 1 error generated.  

1 个答案:

答案 0 :(得分:2)

当你这样做时

TB tb2 = ta;

实际上等于

TB tb2 = TB(ta);

换句话说,临时对象是从ta创建的,然后在 copy-constructor (您的构造函数B)中使用。

这里的问题是非const引用不能绑定到临时对象。解决方案只是使参数成为一个常量引用(由于某种原因你注释掉了)。

使用非标准的移动构造函数(构造函数C),可以将临时对象作为参数,这是rvalue引用如何工作的部分。

相关问题