我有一个下面的程序,我想知道如何调用基类的副本构造函数。
#include <iostream>
using namespace std;
class Base
{
int a;
public:
Base(int xinput):a(xinput)
{
cout<<"Base Ctor:" << a<<endl;
counter++;
}
Base(const Base &obj)
{
a=obj.a;
cout<<"base copy ctr:"<<a<<endl;
counter++;
}
void printcounter()
{
cout<<"Base counter:"<<counter<<endl;
}
virtual ~Base()
{
cout<<"Base Dtor:"<<a<<endl;
counter--;
}
protected:
static int counter;
};
class Derived:public Base
{
int b;
public:
Derived(int xinput,int yinput):Base(xinput),b(yinput)
{
cout<<"Derived Ctor:" << b<<endl;
counter++;
}
void printcounter()
{
cout<<"Derived counter:"<<counter<<endl;
}
~Derived()
{
cout<<"Derived Dtor:" <<b<<endl;
counter--;
}
};
int Base::counter = 0;
Derived d(22,22);
int main()
{
{
Derived D(d);
Base *bptr = new Derived(d);
bptr->printcounter();
delete bptr;
d.printcounter();
}
d.printcounter();
return 0;
}
输出如下。
Base Ctor:22
Derived Ctor:22
base copy ctr:22 //Why is base copy Ctor invoked
base copy ctr:22
Base counter:4
Derived Dtor:22
Base Dtor:22
Derived counter:2
Derived Dtor:22
Base Dtor:22
Derived counter:0
Derived Dtor:22
Base Dtor:22
由于我尚未在派生类中定义副本构造函数,因此隐式副本构造函数被调用。但是如何从那里调用基类的副本构造函数。有人可以告诉内部机制吗?
答案 0 :(得分:1)
由于我尚未在派生类中定义副本构造函数,因此隐式副本构造函数被调用。
正确。
但是如何从那里调用基类的副本构造函数。
您不清楚“如何”是什么意思。隐式副本构造函数将复制所有子对象。这包括基础子对象。
答案 1 :(得分:0)
我找到了想要的答案。
由于派生类没有显式的复制构造函数,因此编译器定义了自己的复制构造函数,并且此复制构造函数具有一个初始化列表,在该列表中将调用复制构造函数。
class A
{
public:
int a;
A(int x){cout<<"A::Default ctr"<<endl;}
A(const A& obj){cout<<"A::copy Ctr"<<endl;}
};
class B:public A
{
public:
B(int x):A(x){cout<<"B::Default ctr"<<endl;}
B(const B& obj):A(obj)
{cout<<"B::copy Ctr"<<endl;}
};
int main()
{
B bobj(10);
B b1obj(bobj);
}
在上面的代码中,如果删除B类复制构造函数的初始化列表中存在的A(obj),则会出现编译错误。因此,很明显,当您有任何需要在基类构造函数中传递的变量作为其初始化的一部分时,派生类的隐式副本构造函数还会提供一个初始化程序列表,在该列表中调用基类副本构造函数。