为什么复制构造函数不“链接"?比如默认构造函数和析构函数? [英] Why aren't copy constructors "chained" like default constructors and destructors?

查看:25
本文介绍了为什么复制构造函数不“链接"?比如默认构造函数和析构函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Why aren't copy constructors chained (like default ctors or dtors) so that before the derived class's copy constructor is called, the base class's copy constructor is called? With default constructors and destructors, they are called in a chain from base-to-derived and derived-to-base, respectively. Why isn't this the case for copy constructors? For example, this code:

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

复制构造函数并没有(不能)真正复制对象,因为 Derived::Derived(const Derived&) 不能访问 basedata改变它.

The copy constructor doesn't (can't) really make a copy of the object because Derived::Derived(const Derived&) can't access basedata to change it.

我是否遗漏了一些关于复制构造函数的基本原理,以至于我的心智模型不正确,或者这种设计是否有一些神秘(或不神秘)的原因?

Is there something fundamental I'm missing about copy constructors so that my mental model is incorrect, or is there some arcane (or not arcane) reason for this design?

推荐答案

复制构造函数不会(不能)真正复制对象,因为 Derived::Derived(const Derived&) 无法访问 pdata改变它.

当然可以:

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

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

If you don't specify a base class constructor in the initializer list, its default constructor is called. If you want a constructor other than the default constructor to be called, you must specify which constructor (and with which arguments) you want to call.

至于为什么是这种情况:为什么复制构造函数应该与任何其他构造函数不同?作为一个实际问题的例子:

As for why this is the case: why should a copy constructor be any different from any other constructor? As an example of a practical problem:

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

struct Derived : Base
{
    Derived(Derived&) { }
};

您希望 Derived 复制构造函数调用哪些 Base 复制构造函数?

Which of the Base copy constructors would you expect the Derived copy constructor to call?

这篇关于为什么复制构造函数不“链接"?比如默认构造函数和析构函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆