前言(注意点)
1、在写派生类的拷贝构造函数时,可以在初始化列表中显示调用父类的拷贝构造函数。如果不在初始化列表中调用父类的拷贝构造函数,则会默认调用父类的无参构造函数(或有默认参数的构造函数)。
2、可以把派生类对象直接给父类的拷贝构造函数做参数(赋值兼容原则)。
接下来分四种可能出现的情况举例讲解。
1、初始化列表中显示调用父类的拷贝构造函数
#include <iostream>
using namespace std;
class Base
{
private:
int m_base;
public:
Base(int b = 0) : m_base(b)
{
cout << "调用了Base的构造函数" << endl;
}
Base(const Base& base) : m_base(base.m_base)
{
cout << "调用了Base的拷贝构造函数" << endl;
}
};
class Derive : public Base
{
private:
int m_derive;
public:
Derive(int b = 0, int d = 0) : Base(b), m_derive(d)
{
cout << "调用了Derive的构造函数" << endl;
}
Derive(const Derive& derive) :Base(derive), m_derive( derive.m_derive) //显示调用父类的拷贝构造函数,并且用子类对象的引用给它赋值
{
cout << "调用了Derive的拷贝构造函数" << endl;
}
};
int main()
{
Derive dr(11, 22);
Derive dc(dr);
return 0;
}
运行结果
可以看到派生类和基类的拷贝构造都正常调用了~
2、不在初始化列表中调用基类的拷贝构造
//只修改了派生类的拷贝构造,不在初始化列表中写基类的拷贝构造
Derive(const Derive& derive) : m_derive( derive.m_derive)
{
cout << "调用了Derive的拷贝构造函数" << endl;
}
运行结果
基类无奈调用了构造函数,而不是拷贝构造。
3、直接把派生类的拷贝构造删了,基类的拷贝构造保留,会发生什么?
#include <iostream>
using namespace std;
class Base
{
private:
int m_base;
public:
Base(int b = 0) : m_base(b)
{
cout << "调用了Base的构造函数" << endl;
}
Base(const Base& base) : m_base(base.m_base)
{
cout << "调用了Base的拷贝构造函数" << endl;
}
};
class Derive : public Base
{
private:
int m_derive;
public:
Derive(int b = 0, int d = 0) : Base(b), m_derive(d)
{
cout << "调用了Derive的构造函数" << endl;
}
//我的拷贝构造没啦!
};
int main()
{
Derive dr(11, 22);
Derive dc(dr);
return 0;
}
运行结果
派生类运行了默认拷贝构造函数,这个默认拷贝构造函数会调用基类的拷贝构造函数,还挺智能。
4、用派生类对象给基类拷贝构造做参数
int main()
{
Derive dr(11, 22);
Base b(dr); //用派生类对象直接拷贝构造基类
return 0;
}
运行结果
很容易理解,这里派生类对象退化成了基类。只会调用基类拷贝,不会调用派生类拷贝。