调用复制构造函数的逻辑

时间:2011-09-14 10:54:00

标签: c++ constructor operator-precedence

class base {
public:
    base(){
        cout << "base constructor" << endl;
    }
    base(const base& rh) {
        cout << "base copy constructor" << endl;
    }
};

//case 1:
class der : public base {
};

//case 2: 
class der : public base {
public:
    der(){
        cout << "der constructor" << endl;
    }
    der(const der& rh) {
        cout << "der copy constructor" << endl;
    }
};

int main() {
 der d;
 der d1(d);
}
  

案例1:der d1(d);调用基类复制构造函数,而在

中      

case-2,基类默认构造函数和der类复制构造函数   被调用。

任何人都可以解释这个逻辑吗?

4 个答案:

答案 0 :(得分:3)

在案例1中,您将获得编译器合成的默认复制构造函数。这被定义为复制基础和成员。

在第2种情况下,您定义了自己的复制构造函数,它会执行您要求它执行的操作。您没有在基类的初始化列表中放置任何内容,因此基类是default-construct [*],与未显式初始化基类的任何其他构造函数相同。如果der有任何数据成员,则不会复制这些成员。

[*]或其他一种初始化,对于非POD类来说是相同的。我永远记不起那些细节。

答案 1 :(得分:2)

默认情况下,派生副本构造函数不会调用基类复制构造函数。如果不告诉派生类复制构造函数调用基类复制构造函数,它仍然需要构造基础子对象,因此它必须调用基本的默认构造函数。

但是在下面的示例中,您将看到可以在派生类的成员initilize列表中添加对基本复制构造函数的调用:

class base {
public:
    base(int i):m_i(i){
        cout << "base constructor" << endl;
    }
    base(const base& rh) {
        m_i = rh.m_i;
        cout << "base copy constructor" << endl;
    }
private:
int m_i;
};

//case 2: 
class der : public base {
public:
    der(int i,int j):base(i),m_j(j){
        cout << "der constructor" << endl;
    }
    der(const der& rh):base(rh) {
        m_j = rh.m_j;
        cout << "der copy constructor" << endl;
    }
private:
    int m_j;
};

int main() {
 der d(1,2);
 der d1(d); //d1.m_i = 1, d1.m_j = 2
}

//result
//base copy constructor
//der copy constructor

答案 2 :(得分:0)

在第一种情况下,您没有为der指定构造函数,因此编译器会为您决定,即将d的数据单独复制到d1,调用复制构造函数base正在进行中。

在第二种情况下,您已指定了复制构造函数,您不会自己调用base的复制构造函数。由于您已经覆盖了der的复制构造函数(它告诉编译器执行您所说的,而不是它想要的),编译器不能假设您想要来调用{的复制构造函数{1}}也是。

答案 3 :(得分:0)

基本上是调用一个copy-con。所以在case-2中调用der的copy-con,如果你愿意,你可以在代码中使用base的copy-con。在第一种情况下,因为你没有实现copy-con,所以它从他的base调用函数,就像它只对基类中实现的任何函数一样。