由[1] [2] 例子看出:子类中实现了拷贝构造和赋值函数,则调用子类的拷贝构造和赋值函数
[1]说明:
子类的拷贝构造中调用父类的拷贝构造;
子类的赋值函数中调用父类的赋值函数
#include<iostream>
using namespace std;
class Parent
{
public:
Parent(){cout<<"Parent constru fun()"<<endl;}
Parent(int a):m_a(a){cout<<"Parent constru fun(int )"<<endl;}
Parent(const Parent&other):m_a(other.m_a)
{
cout<<"Parent copy fun"<<endl;
}
Parent& operator= (const Parent& other)
{
cout<<"Parent =fun"<<endl;
if(this == &other)
return *this;
m_a = other.m_a;
return *this;
}
int geta()
{
return m_a;
}
private:
int m_a;
};
class Child : public Parent
{
public:
Child(){cout<<"Child constru fun( )"<<endl;}
Child(int a, int b):Parent(a),m_b(b){cout<<"Child constru fun(int, int)"<<endl;}
Child(const Child& other) :Parent(other) //调用父类的拷贝构造函数
{
// Parent::Parent(other); //调用父类的拷贝构造函数(同上面的初始化列表)
m_b = other.m_b;
cout<<"Child copyfun"<<endl;
}
Child& operator= (const Child&other)
{
cout<<"Child =fun"<<endl;
Parent::operator=(other); //调用父类的重载赋值运算符
if(this == &other)
return *this;
m_b = other.m_b;
return *this;
}
int getb()
{
return m_b;
}
private:
int m_b;
};
int main()
{
Child child1(2, 3);
cout<<"========================================="<<endl;
Child child2(child1);/*调用子类的拷贝构造,而子类的拷贝构造会先调用父类的拷贝构造函数*/
cout<<"a ="<<child2.geta()<<",b ="<<child2.getb()<<endl;
cout<<"========================================="<<endl;
child2 = child1; /*调用子类的=函数,而子类的=函数会先调用父类的=函数*/
cout<<"a ="<<child2.geta()<<",b ="<<child2.getb()<<endl;
return 0;
}输出结果:
root@ubuntu:/home/ygm# ./mai
Parent constru fun(int )
Child constru fun(int, int)
=========================================
Parent copy fun
Child copyfun
a =2,b =3
=========================================
Child =fun
Parent =fun
a =2,b =3
[2]说明:
子类中拷贝构造函数未调用父类的拷贝构造函数;
子类的赋值号函数中未调用父类的赋值号函数;
#include <iostream>
using namespace std;
class Parent
{
public:
Parent(){cout<<"Parent constru ()"<<endl;}
Parent(int a):m_a(a){cout<<"Parent constru (int)"<<endl;}
Parent(const Parent& other):m_a(other.m_a)
{
cout<<"Parent copy constru"<<endl;
}
Parent& operator= (const Parent& other)
{
cout<<"Parent = fun"<<endl;
if(this == &other)
return *this;
m_a = other.m_a;
return *this;
}
private:
int m_a;
};
class Child : public Parent
{
public:
Child(){cout<<"Child constru ()"<<endl;}
Child(int a, int b):Parent(a), m_b(b){cout<<"Child constru (int, int)"<<endl;}
//未调用父类的拷贝构造
Child(const Child& other)
{
m_b = other.m_b;
cout<<"Child copy constru"<<endl;
}
//未调用父类的赋值函数
Child& operator= (const Child& other)
{
cout<<"Child = fun"<<endl;
if(this == &other)
return *this;
m_b = other.m_b;
return *this;
}
private:
int m_b;
};
int main()
{
Child child1(2, 3);
cout<<"==================="<<endl;
Child child2(child1);
cout<<"==================="<<endl;
child2 = child1;
return 0;
}输出:
root@ubuntu:/home/ygm# ./mai
Parent constru (int)
Child constru (int, int)
===================
Parent constru ()
Child copy constru
===================
Child = fun
[3]说明:
子类中没有实现拷贝构造和赋值函数:则采取默认的流程,
首先调用父类的拷贝构造函数。然后调用子类系统的拷贝构造函数。
首先调用父类的赋值重载函数。然后调用子类系统的赋值重载函数。
#include <iostream>
using namespace std;
class Parent
{
public:
Parent(){cout<<"Parent constru ()"<<endl;}
Parent(int a):m_a(a){cout<<"Parent constru (int)"<<endl;}
Parent(const Parent& other):m_a(other.m_a)
{
cout<<"Parent copy constru"<<endl;
}
Parent& operator= (const Parent& other)
{
cout<<"Parent = fun"<<endl;
if(this == &other)
return *this;
m_a = other.m_a;
return *this;
}
private:
int m_a;
};
class Child : public Parent
{
public:
Child(){cout<<"Child constru ()"<<endl;}
Child(int a, int b):Parent(a), m_b(b){cout<<"Child constru (int, int)"<<endl;}
private:
int m_b;
};
int main()
{
Child child1(2, 3);
cout<<"==================="<<endl;
Child child2(child1);
cout<<"==================="<<endl;
child2 = child1;
return 0;
}输出:
root@ubuntu:/home/ygm# ./mai
Parent constru (int)
Child constru (int, int)
===================
Parent copy constru
===================
Parent = fun
阳光梦总结:
[1]子类中没有实现拷贝构造和赋值函数:
默认的拷贝构造函数的行为:
首先调用父类的拷贝构造函数。然后为自己独有的各成员寻找拷贝构造函数。
如果这个类提供重写的拷贝构造函数,则调用重写的拷贝构造函数,如果成员的类提供的拷贝构造函数是private,编译将无法通过。;
如果这个类没有重写拷贝构造函数,则调用默认的拷贝构造函数;
默认的赋值运算的行为:
首先调用父类的赋值重载函数。然后为自己独有的各成员寻找赋值重载函数
。
如果这个类提供重写的赋值重载函数,则调用重写的
赋值重载函数
,如果成员的类提供的
赋值重载函数
是private,编译将无法通过。;
如果这个类没有重写赋值重载函数,则调用默认的赋值重载函数;
[2]子类中实现了拷贝构造和赋值函数:
则调用子类的拷贝构造和赋值函数