C++四大函数作业解析

  1. 构造
  2. 拷贝构造
  3. 赋值操作符
  4. 析构

1.前面的代码

#include
using namespace std;

class Shape
{
private:
    int no;
};

inline void
Point::setX(int ix){x = ix;}
inline void
Point::setY(int iy){y = iy;}
inline void
Point::getX(){return x;}
Point::getY(){return y;}

class Rectangle:public Shape
{
private:
    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();
    int getWidth();
    int getHeight();
};
Rectangle::Rectangle(int width,int height,int x,int y):width(width),height(height)
{
    leftUp = new Point();
    leftUp ->setX(x);
    leftUp->setY(y);
}
  1. leftUp = new Point()并不是很好,最好写在成员初始化列表里,效率好。

2.拷贝构造函数问题

Rectangle::Rectangle(const Rectangle& other)
{
    this->height = other.height;
    this->width = other.width;
    delete leftUp;
    this->leftUp = new Point();
    this->leftUp = setX(other.leftUp->getX());
    this->leftUp = setY(other.leftUp->getY());
}
  1. delete leftUp问题
  2. leftUp开始的时候是一个随机值—对象,变量,指针未初始化,刚开始在局部变量或者类成员中是一个随机值,即上一次内存留下的原生内存的值
  3. 野指针,幽灵指针…
  4. delete一个0或者null没有问题
  5. 行为未定义—在实际程序中,可能指向正在使用中的对象,delete后会导致程序崩溃,在《Effective C++》里面有一定的描述。
this->leftUp = setX(other.leftUp->getX());
this->leftUp = setY(other.leftUp->getY());

Q:

  1. this->leftUp = new Point(*other.leftUp)
  2. 调用父类的拷贝构造函数,显示调用,写在初始化列表中:Shape(other)
  3. 当leftUp指针为空时,这个时候需要判断。
  4. 要用到初始化列表
  5. 初始化顺序根据类的声明顺序,先父类,后子类成员

典型拷贝构造函数:
1. 考虑空值
2.非指针的成员要单独处理
3.{ }里只对指针成员做处理,其它全部放在初始化列表
4.初始化列表里的顺序与你的标准顺序一致

修改后的拷贝构造函数:

Rectangle::Rectangle(const Rectange& other)
    :Shape(other),heigth(other.heigth),width(other.width)
{
    if(other.leftUp != nullptr){
        this->leftUp = new Point(*other.leftUp);
    }else
    {
        this->leftUp = nullptr;
    }
}

3.赋值操作符

Rectangle&
Rectangle::operator = (const Rectangle& other)
{
    if(this != &other){
        this->height = other.height;
        this->width = other.width;
        delete leftUp;
        this->leftUp = new Point();
        this->leftUp = setX(other.leftUp->getX());
        this->leftUp = setY(other.leftUp->getY());
        return *this;
    }else{
        return *this;
    }
}
  1. 判断是否自我赋值,但是拷贝构造不需要,因为对象还没有创建
  2. 害怕指针未初始化就delete,此为悬浮指针,但是赋值操作符对象构造完成,无法为悬浮指针。
  3. 调用父类的赋值操作符—shape::operator = (other);
  4. 避免悬浮指针—delete后可以赋值nullptr


1.

Rectangle(int width,int height,int x,int y):
    Shape(),width(width),height(height),leftUp(new Point(x,y)){}

Shape( )没有必要去写,默认调用父类的构造函数

2.

Rectangle(const Rectangle& other):
    Shape(),width(other.width),height(other.height),leftUp(new Point(*other.leftUp)){}

Shape(other)
没有判断other.leftUp是否为空

你可能感兴趣的:(C/C++)