为什么复制构造函数不像默认构造函数或析构函数那样"链接"?

Set*_*gie 19 c++ constructor copy-constructor

这可能是一个明显答案或重复的问题.如果有,抱歉,我会删除它.

为什么不复制构造函数(如默认ctors或dtors),以便在调用派生类的复制构造函数之前调用基类的复制构造函数?对于复制构造函数和析构函数,它们分别在从base-to-derived和derived-to-base的链中被调用.为什么复制构造函数不是这种情况?例如,这段代码:

class Base {
public:
    Base() : basedata(rand()) { }

    Base(const Base& src) : basedata(src.basedata) {
        cout << "Base::Base(const Base&)" << endl;
    }

    void printdata() {
        cout << basedata << endl;
    }

private:
    int basedata;
};

class Derived : public Base {
public:
    Derived() { }

    Derived(const Derived& d) {
        cout << "Derived::Derived(const Derived&)" << endl;
    }
};


srand(time(0));


Derived d1;      // basedata is initialised to rand() thanks to Base::Base()

d1.printdata();  // prints the random number

Derived d2 = d1; // basedata is initialised to rand() again from Base::Base()
                 // Derived::Derived(const Derived&) is called but not
                 // Base::Base(const Base&)

d2.printdata();  // prints a different random number
Run Code Online (Sandbox Code Playgroud)

复制构造函数不能(不能)真正制作对象的副本,因为Derived::Derived(const Derived&)无法访问basedata以更改它.

有没有什么基本的我缺少复制构造函数,以便我的心理模型不正确,或者这个设计有一些神秘(或非神秘)的原因?

Jam*_*lis 21

复制构造函数不能(不能)真正制作对象的副本,因为Derived::Derived(const Derived&)无法访问pdata以更改它.

当然可以:

Derived(const Derived& d)
    : Base(d)
{
    cout << "Derived::Derived(const B&)" << endl;
}
Run Code Online (Sandbox Code Playgroud)

如果未在初始值设定项列表中指定基类构造函数,则会调用其默认构造函数.如果要调用默认构造函数以外的构造函数,则必须指定要调用的构造函数(以及使用哪些参数).

至于为什么会这样:为什么复制构造函数与任何其他构造函数有什么不同?作为实际问题的一个例子:

struct Base
{
    Base() { }
    Base(Base volatile&) { } // (1)
    Base(Base const&)    { } // (2)
};

struct Derived : Base
{
    Derived(Derived&) { }
};
Run Code Online (Sandbox Code Playgroud)

其中的Base拷贝构造函数,你会想到Derived拷贝构造函数调用?

  • 默认构造函数与其他构造函数没有区别.对于所有构造函数,除非在初始化列表中显式指定了基类,否则它将是默认构造的,就像初始化列表中未指定的所有成员都将是默认构造的一样. (3认同)