学习资料
• 派生类的赋值运算符/赋值构造函数也必须处理它的基类成员的赋值
定义赋值运算符
【注意】对派生类进行拷贝构造时,如果想让基类的成员也同时拷贝,就一定要在派生类拷贝构造函数初始化列表中显示调用基类拷贝构造函数(当然在函数体内将基类部分的值拷贝也是可以的,只不过它是先用默认构造函数初始化后再修改的基类成员变量的值,效率比较低),否则它会调用基类的默认构造函数,而不会对基类的成员变量拷贝值,这样生成的对象,它的派生类部分和被拷贝的对象派生类部分一样,而基类部分则是默认构造函数的初始化结果。
代码例子1:
1 #include <iostream> 2 using namespace std; 3 4 class A 5 { 6 public: 7 A() { cout << "A default constructor" << endl; } 8 A(A&) { cout << "A copy constructor" << endl; } 9 }; 10 class B : public A 11 { 12 public: 13 B() { cout << "A default constructor" << endl; } 14 B(B &b) { cout << "B copy constructor" << endl; } 15 }; 16 17 int main() 18 { 19 B b; 20 B c = b; 21 return 0; 22 }
输出结果:
代码例子2:
1 #include <iostream> 2 using namespace std; 3 4 class A 5 { 6 public: 7 A() { cout << "A default constructor" << endl; } 8 A(A&) { cout << "A copy constructor" << endl; } 9 }; 10 class B : public A 11 { 12 public: 13 B() { cout << "A default constructor" << endl; } 14 B(B &b) : A(b) { cout << "B copy constructor" << endl; } 15 }; 16 17 int main() 18 { 19 B b; 20 B c = b; 21 return 0; 22 }
输出结果:
定义派生类赋值运算符
1 class base 2 { 3 public: 4 base(int initialvalue = 0): x(initialvalue) {} 5 6 private: 7 int x; 8 }; 9 10 class derived : public base 11 { 12 public: 13 derived(int initialvalue): base(initialvalue), y(initialvalue) {} 14 derived& operator=(const derived& rhs); 15 16 private: 17 int y; 18 }; 19 20 逻辑上说,derived的赋值运算符应该象这样: 21 derived& derived::operator = (const derived& rhs) // 错误的赋值运算符 22 { // 请注意d1的base部分没有被赋值操作改变。 23 if (this == &rhs) 24 return *this; 25 y = rhs.y; 26 return *this; 27 } 28 29 不幸的是,它是错误的,因为derived对象的base部分的数据成员x在赋值运算符中未受影响。例如,考虑下面的代码段: 30 31 void assignmenttester() 32 { 33 derived d1(0); // d1.x = 0, d1.y = 0 34 derived d2(1); // d2.x = 1, d2.y = 1 35 36 d1 = d2; // d1.x = 0, d1.y = 1 37 } 38 39 40 derived& derived::operator=(const derived& rhs) // 正确的赋值运算符 41 { 42 if (this == &rhs) return *this; 43 44 base::operator=(rhs); // 调用this->base::operator= 45 y = rhs.y; 46 47 return *this; 48 }