您的位置:首页 > 编程语言 > C语言/C++

C++面向对象编程<八>:小练习之Big three函数

2016-02-23 12:47 615 查看

问题描述

为 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: