本文主要对派生类的拷贝构造函数通过代码进行各种试验
主要几个关注点:
1.自定义的拷贝构造函数中未初始化的成员,编译器会隐式帮助初始化吗
2.派生类的拷贝构造函数在不指定基类构造函数的情况下调用基类的哪个构造函数,会自动调用基类的拷贝构造函数吗
3.在未定义拷贝赋值运算符的情况下,各种赋值运算调用的是哪个函数
#include<iostream>
#include<string>
using namespace std;
class Base
{
public:
int a,b;
Base(){a=0;b=0;}
Base(int t){a=t;}
Base(const Base& t){a=t.a;}
};
class Derived:public Base
{
public:
Derived(){b=2;c=2;}
Derived(int t){a=1;b=1;c=t;}
Derived(const Derived& t):Base(t){}
int c;
};
class Derived2:public Base
{
public:
Derived2(const Derived& t){b=t.b;c=4;}
//Derived2& operator=(const Derived& t){c=4;return *this;}
int c;
};
int main()
{
Derived d1(3);
Derived d2(d1);
Derived d3;
d3=d1;
Derived2 d4=d1;
d4=d2;
cout<<d1.a<<" "<<d1.b<<" "<<d1.c<<endl;
cout<<d2.a<<" "<<d2.b<<" "<<d2.c<<endl;
cout<<d3.a<<" "<<d3.b<<" "<<d3.c<<endl;
cout<<d4.a<<" "<<d4.b<<" "<<d4.c<<endl;
system("pause");
return 0;
}
输出结果为:
1 1 3
1 u u
1 1 3
0 u 4
u为未初始化的值
解析:
1.
Derived d1(3);
调用Derived(int),然后调用Base()
2.
Derived d2(d1);
调用Derived(const Derived&),然后调用Base(const Base&)。 从结果发现编译器并没有帮助初始化(关注点1)
3.
Derived d3;
d3=d1;
第二句:调用编译器暗暗定义的拷贝赋值运算符 Derived& operator=(const Derived&),即将d1的成员挨个拷贝给d3。(关注点3)
4.
Derived2 d4=d1;
d4=d2;
第一句:调用Derived2(const Derived&),然后调用Base()。 声明时的“=”是调用拷贝构造函数而非拷贝赋值运算符。(关注点3)
第二句:还是调用Derived2(const Derived&)。 因为与编译器暗暗定义的拷贝赋值运算符的形参不同。 (关注点3)
至于关注点2,结论是各派生类构造函数在缺省情况下一概会先调用基类的默认构造函数(即Base()),而不是其他的构造函数