题目:

为下面的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();

};

解析:

一 构造函数:

1.尽量使用初始化列表;

2.对leftUp指针的构造,leftUp指向一个Point对象,构造函数需要在堆内生成一个新的point对象,并用leftUp指向该对象

inline
Rectangle::Rectangle(int width,int heigt, int x,int y):width(width),height(height),leftUp(new Point(x,y)){}
//尽量使用初始化列表,包括对leftUp的初始化

二 拷贝构造函数:

1.尽量使用初始化列表

2.注意对父类继承而来的no的拷贝构造,方法是调用父类shape的拷贝构造函数 Shape(other)

3.对this->leftUp的拷贝构造,调用Point的拷贝构造函数,这样在Point内部有变化时,避免大量修改。

 this->leftUp = new Point(*other.leftUp); 

4.针对other.leftUp是否为空的讨论,空指针情况没必要在堆内生成对象,同时当other.leftUp为空时,this->leftUp初始默认是随机值,要对他进行赋值为空指针。

完整的拷贝构造函数:

inline
Rectangle::Rectangle(const Rectangle& other)
:Shape(other),width(other.width),height(other.height){ // 注意对继承而来对象no的拷贝构造,通过调用父类的拷贝构造函数
if(other.leftUp != NULL){ //针对other.leftUp是否为空的讨论,空指针情况没必要在堆内生成对象
this->leftUp = new Point(*other.leftUp); //调用Point的拷贝构造函数,这样在Point内部有变化时,避免大量修改。
}
else{
this->leftUp = NULL; //leftUp初始默认是随机值,要对他进行赋值为空指针。
}
}

三 赋值操作符

1.赋值操作符往往需要首先判定自己给自己赋值的情况,避免内存泄露

if(this == &other){
return *this;
}

2.调用父类的赋值操作符,完成对父类继承部分的赋值操作,方法如下:

    Shape::operator=(other);     //调用父类的赋值操作符,完成对父类继承部分的赋值操作 

3.需要对leftUp,other.leftUp是否为空进行讨论

other.leftUp为空时,直接释放this->leftUp空间,并将其赋为空即可;

other.leftUp不为空时,

若this->leftUp也不为空,则直接将other->leftUp指向的内容赋值给this->leftUp指向的内容即可;

若this->leftUp为空,创建新的Point对象

Rectangle& Rectangle::operator= (const Rectangle& other){
if(this == &other){ //赋值操作符往往需要首先判定自己给自己赋值的情况,避免内存泄露
return *this;
}
Shape::operator=(other); //调用父类的赋值操作符,完成对父类继承部分的赋值操作
this->width = other.width;
this->height = other.height; if(other.leftUp != NULL){
if(leftUp != NULL) {
*leftUp = *other.leftUp; //不必删除leftUp再重新构建,直接进行赋值即可(解指针,调用point类的赋值操作符即可)
}
else{
leftUp = new Point(*other.leftUp); //leftUp为空,不能解指针,需要创建一个新对象
}
}
else{
delete leftUp;
this->leftUp = NULL;
}
return *this;
}

四 析构函数

Rectangle:: ~Rectangle(){
delete leftUp;
}

五 整体代码和其他注意事项

1.Rectangle赋值构造函数,构造顺序:先父类,后按照子类中声明的顺序,与初始化列表中的顺序无关。

2.正确区分拷贝构造函数和赋值操作符。

拷贝构造函数是构造函数,也就是创建新对象时,所以一个对象存在,一个对象尚未存在;

赋值操作符使用时,两个对象必然都是存在的,所以需要讨论的问题是是否自我赋值等等。

3 面对此类问题方法:

先忘掉语法,画内存模型

本例即

然后写的时候分析指针是否为空;

拷贝构造就是一边有,一边没有;赋值操作符就是两边都有;

结合指针是否为空,可以分析出上述的注意事项。

class Shape
{
int no;
}; class Point
{
private:
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 heigt, int x,int y):width(width),height(height),leftUp(new Point(x,y)){}
//尽量使用初始化列表,包括对leftUp的初始化 inline
Rectangle::Rectangle(const Rectangle& other)
:Shape(other),width(other.width),height(other.height){ // 注意对继承而来对象no的拷贝构造,通过调用父类的拷贝构造函数
if(other.leftUp != NULL){ //针对other.leftUp是否为空的讨论,空指针情况没必要在堆内生成对象
this->leftUp = new Point(*other.leftUp); //调用Point的拷贝构造函数,这样在Point内部有变化时,避免大量修改。
}
else{
this->leftUp = NULL; //leftUp初始默认是随机值,要对他进行赋值为空指针。
}
} Rectangle& Rectangle::operator= (const Rectangle& other){
if(this == &other){ //赋值操作符往往需要首先判定自己给自己赋值的情况,避免内存泄露
return *this;
}
Shape::operator=(other); //调用父类的赋值操作符,完成对父类继承部分的赋值操作
this->width = other.width;
this->height = other.height; if(other.leftUp != NULL){
if(leftUp != NULL) {
*leftUp = *other.leftUp; //不必删除leftUp再重新构建,直接进行赋值即可(解指针,调用point类的赋值操作符即可)
}
else{
leftUp = new Point(*other.leftUp); //leftUp为空,不能解指针,需要创建一个新对象
}
}
else{
delete leftUp;
this->leftUp = NULL;
}
return *this;
} Rectangle:: ~Rectangle(){
delete leftUp;
}

c++ 构造函数,拷贝构造函数,析构函数与赋值操作符的更多相关文章

  1. C++构造函数 & 拷贝构造函数 & 派生类的构造函数 & 虚继承的构造函数

    构造函数 ,是一种特殊的方法 .主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 .特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数 ...

  2. [c++基础]3/5原则--拷贝构造函数+拷贝赋值操作符

    /* * main.cpp * * Created on: Apr 7, 2016 * Author: lizhen */ #include <iostream> #include &qu ...

  3. C++中的赋值操作符重载和拷贝构造函数

    1,关于赋值的疑问: 1,什么时候需要重载赋值操作符? 2,编译器是否提供默认的赋值操作符? 2,关于赋值的疑问: 1,编译器为每个类默认重载了赋值操作符: 1,意味着同类型的类对象可以相互赋值: 2 ...

  4. C++中复制构造函数与重载赋值操作符总结

    前言 这篇文章将对C++中复制构造函数和重载赋值操作符进行总结,包括以下内容: 1.复制构造函数和重载赋值操作符的定义: 2.复制构造函数和重载赋值操作符的调用时机: 3.复制构造函数和重载赋值操作符 ...

  5. C++基础 (3) 第三天 构造函数 构造函数初始化列表 拷贝构造函数 析构函数 静态成员变量

    // 同类之间无私处 2构造函数 3析构函数 4构造函数的种类和析构函数的顺序 结论:析构函数的调用顺序,跟对象的构造顺序相反,谁先构造,谁最后一个被析构. 拷贝构造函数: 注意: 等号写在下面和写在 ...

  6. C++中复制构造函数和赋值操作符

    先看一个例子: 定义了一个类:

  7. C++中构造函数,拷贝构造函数和赋值函数的区别和实现

    C++中一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法.下面就详细比较下三者之间的区别以及它们的具体实现 1.构造函数 构造函数是一种特殊的类成员函数,是当创建一个类的对象 ...

  8. C++中的构造函数,拷贝构造函数,赋值函数

    C++中一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法.下面就详细比较下三者之间的区别以及它们的具体实现 1.构造函数 构造函数是一种特殊的类成员函数,是当创建一个类的对象 ...

  9. C++ 类 & 对象-类成员函数-类访问修饰符-C++ 友元函数-构造函数 & 析构函数-C++ 拷贝构造函数

    C++ 类成员函数 成员函数可以定义在类定义内部,或者单独使用范围解析运算符 :: 来定义. 需要强调一点,在 :: 运算符之前必须使用类名.调用成员函数是在对象上使用点运算符(.),这样它就能操作与 ...

随机推荐

  1. Js/Jquery获取iframe中的元素 在Iframe中获取父窗体的元素方法

    在web开发中,经常会用到iframe,难免会碰到需要在父窗口中使用iframe中的元素.或者在iframe框架中使用父窗口的元素 js 在父窗口中获取iframe中的元素  1. 格式:window ...

  2. Netbeans Platform 工程,免安装JDK

    使用Netbeans 6.8 创建了一个Netbeans Platform 工程,以Zip形式发布后, 按照以下操作,可 以在客户端免安装JDK: 1. 从已安装JDK的计算机中,提取JDK:eg. ...

  3. Windows 7 不同安装模式简要区别(图解)

    ★ 你可能对GHOST不支持AHCI感到迷惑,实际上,写过GHOST一键安装批处理的都知道一个叫FINDCD.EXE的小程序,可是这个程序老 了,AHCI模式光驱他找不到了,找不到光驱动意味着光盘中G ...

  4. lambda表达式和ef的语句转化

    这两者转化可以用linqpad进行转化, 首先推荐一个网站可以了解一下orderby的排序方式 http://www.csharpwin.com/csharpspace/614.shtml 然后下面有 ...

  5. C++视频课程小结(2)

    C++远征之离港篇 章节介绍: 每章小结: 第一章:大致讲了一下本章会讲的内容:引用vs指针.const vs #define(这个我在C里都没用过).函数变得更强大.内存管理要小心之类的. 第二章: ...

  6. 在drupal7中动态的为某个内容类型添加字段

    $myField_name = "my_new_field_name"; if(!field_info_field($myField_name)) // check if the ...

  7. ZOJ 3597 Hit the Target! (线段树扫描线 -- 矩形所能覆盖的最多的点数)

    ZOJ 3597 题意是说有n把枪,有m个靶子,每把枪只有一发子弹(也就是说一把枪最多只能打一个靶子), 告诉你第 i 把枪可以打到第j个靶, 现在等概率的出现一个连续的P把枪,在知道这P把枪之后,你 ...

  8. 【转贴】Linux系统NGINX负载均衡404错误处理方法

    NGINX负载均衡404错误处理方法 使用NGINX 实现负载均衡,但一组服务器的数据不是实施同步,主服务器有了数据要过段时间才同步到其他服务器 upstream   image.stream.com ...

  9. 转载php在IIS中运行

    在IIS中配置PHP运行环境简单步骤 安装 IIS 7.0 打开 Control Panel\Programs\Programs and Features\Turn Windows features ...

  10. AWstat(linux下)

    一.AWstat统计信息 AWstat是一个非常简洁而且功能强大的统计工具.它可以统计你站点的如下信息: 1 访问量.访问次数.页面浏览量.点击数.数据流量等精确到每月.每日.每小时 2 访问者国家. ...