1、注意
1、Rectangle赋值构造函数,构造顺序:先父类,后子类
2、正确区分拷贝构造函数和赋值操作符:
*拷贝构造函数是构造函数,也就是创建新对象时,所以一个对象存在,一个对象尚未存在
*赋值操作符使用时,两个对象必然都是存在的,所以需要讨论的问题是是否自我赋值等等
3、面对此类问题方法
*拷贝构造就是一边有,一边没有;赋值操作符就是两边都有 ·结合指针是否为空,可以分析出上述的注意事项
4、类Rectangle展现了一个在所有c++环境下都会产生的bug:
*当Rectangle的拷贝创建时,没有拷贝其基类Shape部分。
*当然,这个Rectangle对象的Shape部分还是创建了,但它是用Shape的缺省构造函数创建的,成员no被初始化为0(缺省构造函数的缺省参数值)
*为避免这个问题,Rectangle的拷贝构造函数必须保证调用的是Shape的拷贝构造函数而不是Shape的缺省构造函数。
*这很容易做,只要在Rectangle的拷贝构造函数的[成员初始化列表]里对Shape指定一个初始化值即可
5、子类拷贝构造函数不会自动调用父类的拷贝构造函数,而是调用父类默认构造函数
2、代码实例
#include <iostream>
using namespace std;
class Shape
{
public:
Shape(){};
Shape(int n) :no(n){}
Shape(const Shape& other):no(other.no){}
int no;
};
class Point
{
public:
Point(int x, int y) :x(x), y(y){}
int x;
int y;
};
class Rectangle :public Shape
{
int width;
int height;
Point* leftUp;
public:
Rectangle(int w, int h, int x, int y);
Rectangle(const Rectangle& other);
Rectangle& operator=(const Rectangle& other);
~Rectangle();
};
Rectangle::Rectangle(int w, int h, int x, int y) :width(w), height(h), Shape(w)
{
leftUp = new Point(x, y);
}
Rectangle::Rectangle(const Rectangle& other):Shape(other)
{
width = other.width;
height = other.height;
if (this->leftUp != NULL)
{
this->leftUp = NULL;
}
if (other.leftUp != NULL)
{
this->leftUp = new Point(*other.leftUp);
}
}
Rectangle& Rectangle::operator= (const Rectangle& other)
{
if (this == &other)
return *this;
Shape::operator=(other);
this->width = other.width;
this->height = other.height;
if (this->leftUp != NULL)
{
delete this->leftUp;
this->leftUp = NULL;
}
this->leftUp = new Point(*other.leftUp);
return *this;
}
Rectangle::~Rectangle()
{
delete this->leftUp;
this->leftUp = NULL;
}
int main()
{
Rectangle rect(20, 10, 3, 5);
Rectangle rectCopy(rect);
Rectangle rectAssign(10, 5, 1, 2);
rectAssign = rect;
}
|