问题描述
为 Rectangle 类实现构造函数,拷贝构造函数,赋值操作符,析构函数。
如下
class Shape
{
int no;
};
class Point
{
int x;
int y;
};
class Rectangle: public Shape
{
int width;
int height;
Point * leftUp;
public:
Rectangle(int width, int height, int x, int y);
Rectangle(const Rectangle& other);
Rectangle& operator=(const Rectangle& other);
~Rectangle();
};
程序
- 构造函数
inline Rectangle::Rectangle(int width, int height, int x, int y)
: width_(width), height_(height), leftUp_(new Point(x,y))
{
}
- 拷贝构造函数
先看程序1
inline Rectangle::Rectangle(const Rectangle& other)
: width_(other.width_), height_(other.height_), leftUp_(new Point(*other.leftUp_))
{
this->no_ = other.no_;//错误的,no_是私有成员,不能访问即使是public的,也不要使用这种写法,因为若Shape类仔增加一个成员变量,则需要更改程序
}
/*
问题1见上标识
问题2:other的leftUp_有可能为NULL,需要判断
问题3:忘记了父类Shape
*/
程序2
inline Rectangle::Rectangle(const Rectangle& other)
: Shape(other), width_(other.width_), height_(other.height_)
{
if (other.leftUp_ != NULL)
{
leftUp_ = new Point(*(other.leftUp_));
}
else
{
leftUp_ = NULL; //别忘记,若没有这行,默认是给随机值。
}
}
/*
解释下Shape(other)
首先任何一个类都有拷贝构造函数的。 其次传递other Shape(const Shape& s) ,rectangle是shape的子类,因此可以传递。可以把子类对象当作父类对象来传递。
*/
- 拷贝赋值函数
先看程序1
inline Rectangle::operator = (const Rectangle& other)
{
if (this != &other)
{
delete leftUp_;
leftUp_ = new Point(*(other.leftUp_));
width_ = other.width_;
height_ = other.height_;
}
return *this;
}
/*
首先没有考虑父类,其次也没有考虑other的leftUp_是否为0
*/
程序2
inline Rectangle::operator = (const Rectangle& other)
{
//先调用父类的=函数
if (this == other)
{
return *this;
}
Shape::operator = (other); //考虑父类
width_ = other.width_;
height_ = other.height_;
delete leftUp_;
if (other.leftUp != NULL)
{
leftUp_ = new Point(*(other.leftUp_));
}
else
{
leftUp_ = NULL;
}
return *this;
}
/*
该做法不一定好,其实没有必要一定得delete leftUp_
*/
程序3
inline Rectangle::operator = (const Rectangle& other)
{
//先调用父类的=函数
if (this == other)
{
return *this;
}
Shape::operator = (other);
width_ = other.width_;
height_ = other.height_;
// delete leftUp_; 其实没必要delete,可以直接赋值。
if (leftUp_ != NULL)
{
if (other.leftUp != NULL)
{
*leftUp_ = *(other.leftUp_);
}
else
{
delete leftUp_;
leftUp_ = NULL;
}
}
else
{
if (other.leftUp != NULL)
{
leftUp_ = new Point(*(other.leftUp_));
}
//都为NULL就不管了
}
return *this;
}
- 析构函数
inline Rectangle::~Rectangle()
{
delete leftUp_;
leftUp_ = NULL // 没有必要的,
}
- 完整程序
#ifndef _RECTANGLE_
#define _RECTANGLE_
class Shape
{
int no_;
};
class Point
{
int x_;
int y_;
public:
Point(int x, int y) : x_(x), y_(y) {}
};
class Rectangle: public Shape
{
int width_;
int height_;
Point *leftUp_;
public:
Rectangle(int width, int height, int x, int y);
Rectangle(const Rectangle& other);
Rectangle& operator=(const Rectangle& other);
~Rectangle();
};
inline Rectangle::Rectangle(int width, int height, int x, int y)
: width_(width), height_(height), leftUp_(new Point(x,y))
{
}
inline Rectangle::Rectangle(const Rectangle& other)
: Shape(other), width_(other.width_), height_(other.height_)
{
if (other.leftUp_ != NULL)
{
this->leftUp_ = new Point(*(other.leftUp_));
}
else
{
this->leftUp_ = NULL;
}
}
inline Rectangle& Rectangle::operator = (const Rectangle& other)
{
if (this == &other)
return *this;
Shape::operator=(other);
width_ = other.width_;
height_ = other.height_;
if (leftUp_ != NULL)
{
if (other.leftUp_ != NULL)
{
*leftUp_ = *(other.leftUp_);
}
else
{
delete leftUp_;
leftUp_ = NULL;
}
}
else
{
if (other.leftUp_ != NULL)
{
leftUp_ = new Point(*(other.leftUp_));
}
}
return *this;
}
Rectangle::~Rectangle()
{
delete this->leftUp_;
}
#endif
总结
- 别忘记考虑父类
- 考虑代码复用性
- 理解内存模型
- 注意delete后,只是回收内存,指针值是不变的,delete后是多少还是多少,因此delete后注意置指针值为NULL