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
相关文章推荐
- ios海哥开发笔记 (海哥原创,C语言之堆栈入门——堆和栈的区别 )
- iOS海哥开发笔记 (海哥原创,C语言之内存四区模型和函数调用模型)
- 程序员面试题精选100题(32)-不能被继承的类[C/C++/C#]
- 程序员面试题精选100题(30)-赋值运算符重载函数[C/C++/C#]
- 解析C++中不能重载为友元函数的四个运算符
- 基于c++实现的几种排序算法
- c与c++区别
- 在C语言中,double、long、unsigned、int、char类型数据所占字节数
- Service.cpp:10:28: error: within this context
- C与C++内存机制的不同
- C/C++ 内存分配情况
- C语言(头文件格式)
- C++类内存分布
- 常见C++内存池技术
- 关于C++重定义问题
- 【C++】static关键字的作用
- 【C++】友元函数
- 103. Binary Tree Zigzag Level Order Traversal
- C++封装继承多态总结
- C++STL 常用 函数 用法