C++ 为什么C++;调用其子复制构造函数时,复制构造函数的行为是否不同?

C++ 为什么C++;调用其子复制构造函数时,复制构造函数的行为是否不同?,c++,C++,我有以下玩具类别A和它的孩子B: #include <iostream> using namespace std; class A { protected: int a; public: A():a(1){cout<<"A default constructor..."<<endl;} A(int i):a(i){cout<<"A non-default constructor..

我有以下玩具类别A和它的孩子B:

#include <iostream>

using namespace std;

class A
{
    protected:
        int a;
    public:
        A():a(1){cout<<"A default constructor..."<<endl;}
        A(int i):a(i){cout<<"A non-default constructor..."<<endl;}
        A(const A &ao){cout<<"A copy constructor..."<<endl; a=ao.a;}
};

class B:public A
{
    private:
       int b;
    public:
       B(int i,int j):A(i),b(j){cout<<"B constructor..."<<endl;}
       //B(const B &bo){cout<<"B copy constructor... "<<endl; b=bo.b;}
       void print(){cout<<endl<<"class B, a: "<<a<<" b: "<<b<<endl<<endl;}
};

int main()
{
    B b1(3,8);
    b1.print();
    B b2=b1;
    b2.print();
}
#包括
使用名称空间std;
甲级
{
受保护的:
INTA;
公众:

A():A(1){cout这是标准行为。主要是为了一致性:任何未显式调用特定基类构造函数的用户定义构造函数都将调用默认构造函数。为什么复制构造函数会有所不同?

这里应用初始化规则的顺序。您只能通过提供wn构造函数。

当您为派生类编写构造函数(任何构造函数)时,您可以(而且通常必须)这样做显式初始化该构造函数的初始值设定项列表中的基类子对象。如果未能初始化,则编译器将隐式调用这些基类子对象的默认构造函数(假设它们可用)。此规则适用于所有用户定义的构造函数

这正是在您的案例中发生的情况。您忘记在
B::B(const B&)
的构造函数中初始化base
A
,因此默认构造函数用于该base。事实上,
B::B(const B&)
是一个复制构造函数,在这种情况下没有任何区别。同样,对于所有类型的用户定义构造函数,它都是这样工作的


现在,如果您不提供用户定义的复制构造函数,那么编译器将尝试隐式提供on。隐式定义的复制构造函数将尝试调用所有基类的复制构造函数。语言规范只是说编译器提供的复制构造函数的行为是这样的,这就是“为什么”的答案问题。

您没有注意到的是,成员数据的处理方式与基类数据的处理方式相同:如果编译器提供复制构造函数,则通过复制构造进行初始化;如果编写存根复制构造函数,则通过默认构造进行初始化


通过实现复制构造函数,您告诉编译器,您将决定如何初始化成员和基类。如果没有其他说明,这些将使用默认方法初始化。

我的问题是:为什么我的复制构造函数没有显式调用基类s的复制构造函数,实际上称为默认构造函数而不是复制构造函数?如果我不提供复制构造函数,为什么合成的复制构造函数称为基复制构造函数而不是基默认构造函数?@HailiangZhang,因为这是标准对它的定义。你在问它背后的动机吗?为了一致性。