c++ - 为什么隐式复制构造函数调用基类复制构造函数而定义的复制构造函数不调用?

标签 c++ language-design copy-constructor

考虑一个类层次结构,其中 A 是基类,B 派生自 A

如果B中没有定义拷贝构造函数,编译器会合成一个。当被调用时,这个复制构造函数将调用基类复制构造函数(即使是合成的,如果用户没有提供的话)。

#include <iostream>

class A {
    int a;
public:
    A() {
        std::cout << "A::Default constructor" << std::endl;
    }

    A(const A& rhs) {
        std::cout << "A::Copy constructor" << std::endl;
    }
};

class B : public A {
    int b;
public:
    B() {
        std::cout << "B::Default constructor" << std::endl;
    }
};

int main(int argc, const char *argv[])
{
    std::cout << "Creating B" << std::endl;
    B b1;
    std::cout << "Creating B by copy" << std::endl;
    B b2(b1);
    return 0;
}

输出:

Creating B
A::Default constructor
B::Default constructor
Creating B by copy
A::Copy constructor

如果用户在B中定义了自己的拷贝构造函数,当被调用时,这个拷贝构造函数会调用基类默认构造函数,除非调用了基类拷贝构造函数显式存在(例如在初始化列表中)。

#include <iostream>

class A {
    int a;
public:
    A() {
        std::cout << "A::Default constructor" << std::endl;
    }

    A(const A& rhs) {
        std::cout << "A::Copy constructor" << std::endl;
    }
};

class B : public A {
    int b;
public:
    B() {
        std::cout << "B::Default constructor" << std::endl;
    }
    B(const B& rhs) {
        std::cout << "B::Copy constructor" << std::endl;
    }
};

int main(int argc, const char *argv[])
{
    std::cout << "Creating B" << std::endl;
    B b1;
    std::cout << "Creating B by copy" << std::endl;
    B b2(b1);
    return 0;
}

输出:

Creating B
A::Default constructor
B::Default constructor
Creating B by copy
A::Default constructor
B::Copy constructor

我的问题是,为什么用户定义的复制构造函数不调用基类复制构造函数作为默认行为?

最佳答案

所有基子构造函数都调用父默认构造函数。这就是标准的定义方式。正如您所指出的,如果您希望派生类 B 调用 A 的复制构造函数,您必须明确要求它

#include <iostream>

class A {
int a;
public:
A() {
    std::cout << "A::Default constructor" << std::endl;
}

A(const A& rhs) {
    std::cout << "A::Copy constructor" << std::endl;
}
};

class B : public A {
int b;
public:
B() {
    std::cout << "B::Default constructor" << std::endl;
}
B(const B& rhs):A(rhs) {
    std::cout << "B::Copy constructor" << std::endl;
}
};

int main(int argc, const char *argv[])
{
std::cout << "Creating B" << std::endl;
B b1;
std::cout << "Creating B by copy" << std::endl;
B b2(b1);
return 0;
}

之所以如此,是因为编译器无法知道每个不同的构造函数应该调用哪个父构造函数,因此我们有 默认构造函数 对于所有其他构造函数,您必须明确声明它们。

输出:

Creating B
A::Default constructor
B::Default constructor
Creating B by copy
A::Copy constructor
B::Copy constructor

关于c++ - 为什么隐式复制构造函数调用基类复制构造函数而定义的复制构造函数不调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9178204/

相关文章:

c++ - 模板成员变量特化

c++ - 双缓冲故障(2013 年 12 月 17 日更新)

C++在尝试覆盖方法时无法实例化抽象类

functional-programming - 函数式编程和方程求解器

c++ - 深拷贝构造函数数组类C++

c++ - C c;之间有什么区别吗?和 C c = C();?

c++ - 移动 std::unique_ptr 时出错

c++ - 为什么引用在 C++ 中不可重新安装

programming-languages - 寻找允许您更改真假的编程语言

c++ - 转换构造函数