拷贝构造函数

同一个类的对象在内存中有完全相同的结构,如果作为一个整体进行复制或称拷贝是完全可行的。
这个拷贝过程只需要拷贝数据成员,而函数成员是共用的(只有一份拷贝)。在建立对象时可用同一类
的另一个对象来初始化该对象的存储空间,这时所用的构造函数称为拷贝构造函数(Copy
Constructor)。

using namespace std;
class Empty
{private:int value1;int value2;
public:Empty() {}//构造函数~Empty() {}//析构函数Empty(const Empty&) {}//拷贝构造函数
};

在类中如果没有显式给出拷贝构造函数时,则C++编译器自动给出一个缺省的拷贝构造函数。

using namespace std;
class Empty
{private:int value1;int value2;
public:Empty(int x, int y) :value1(0) { value1 = x; value2 = y; }//构造函数~Empty() {}//析构函数void print()const{cout << "value1= " << value1 << "value2= " << value2 << endl;}
};
int main()
{Empty a(2, 2);Empty b(33, 10);Empty c(0, 0);Empty d(b);d.print();return 0;
}

打印结果:

如果我们给出了拷贝构造函数,那么则按函数重载的规律,调用合适的构造函数。

using namespace std;
class Empty
{private:int value1;int value2;int value3;//const char *a = "hello";
public:Empty(int x, int y) :value1(0) { value1 = x; value2 = y; }~Empty() {}Empty(const Empty& x) :value1{ 3 }, value2{ 3 }{//value1 = x.value1;//value2 = x.value2;}void print()const{cout << "value1= " << value1 << "value2= " << value2 << endl;}
};int main()
{Empty a(2, 2);Empty b(33, 10);Empty c(0, 0);Empty d(a);//c = a + b;d.print();return 0;
}

打印结果value1=3,value2=3。

class Empty
{private:int value1;int value2;
public:Empty() {}Empty(int x,int y) :value1(0) { value1 = x; value2 = y; }//构造函数~Empty() {}//析构函数Empty(const Empty&) {}//拷贝构造函数Empty& operator+(const Empty& x) {Empty tmp (x.value1 + value1, x.value2 + value2);return tmp;}//运算符重载函数:等号的赋值重载Empty* operator &() { return this; }//取地址函数const Empty* operator &()const { return this; }//引用运算符的重载:取地址void print()const{cout <<"value1= "<< value1 <<"value1= "<< value2 << endl;}
};
Empty  &fun(int x, int y)//此处的返回值为什么不能是对象
{Empty tmp(x,y);return tmp;
}
int main()
{Empty a(2,2);Empty b(3,0);Empty e;e = fun(1234,5678);e.print();return 0;
}
using namespace std;
#if 1
class Complex
{private:int _Real;int _Image;
public:Complex(int r = 0, int i = 0) :_Real(r), _Image(i){cout << "Create Complex" << this << endl;}~Complex() { cout << "Destroy Complex" << this << endl; }Complex(const Complex& cx) :_Real(cx._Real),_Image(cx._Image){ cout << "Copy Create Complex" << this << endl; }void show(){cout << "_Real = " << _Real << " _Image = " << _Image << endl;}Complex   operator=(const Complex & cx){if (this != &cx){_Real = cx._Real;_Image = cx._Image;}cout << "opreator =" << endl;return *this;}};
int main()
{Complex c1(1, 2);Complex c2(c1);Complex c3;c3 = c2;c3.show();return 0;}

下图输出的是 赋值重载函数返回值不加引用的情况:

Complex operator=(const Complex & cx)

而下图是 赋值重载函数返回值加引用的情况:

Complex & operator=(const Complex & cx)

由对比可以发现,当赋值重载函数返回值是对象时,当函数消亡之前,在主函数栈帧中创建一个临时的对象,把这个对象的成员一一赋值给C3后此临时对象就死掉了。
而当赋值重载函数返回值是对象的引用时,在函数退出之前不会创建一个临时对象,只返回对象(此this指针)的地址。

注意,当以引用返回时,一定注意此返回值是在哪儿定义的。当函数的生存期结束不影响此返回对象时,可以以引用返回。

深拷贝和浅拷贝

在这里插入代码片

深赋值和浅赋值

class MyString
{char* str;
public:MyString(const char* p = nullptr){if (p != nullptr){int n = strlen(p) + 1;str = new char[n];strcpy_s(str, n, p);}else{str = new char[1];str[0] = '\0';}cout << "Create MyString" << this << endl;}~MyString(){delete[]str;str = nullptr;cout << "Destroy MyString: " << this << endl;}MyString(const MyString& s){int n = strlen(s.str) + 1;str = new char[n];strcpy_s(str, n, s.str);cout << "Copy Create MyString: " << this << endl;}void Print() const{cout << str << endl;}
MyString & fun()
{MyString tmp("hello");return tmp;
}
int main()
{MyString s1;s1.Print();s1 = fun();s1.Print();return 0;
}


我们可以看到这里打印的不是hello而是随机值。为什么?

当我们用fun()函数去初始化s1时,函数结束返回时以引用的方式,返回的是一个地址,当函数结束,栈帧归还给系统。再次调用时这个地址就是一个悬空指针,所以打印随机值。

【拷贝构造函数、(浅)深拷贝、(浅)深赋值】相关推荐

  1. C++拷贝构造函数:深拷贝和浅拷贝

    1 拷贝构造函数 它是一种特殊的构造函数,由编译器调用来完成一些基于同一类的其他对象的构件及初始化. 1.1 拷贝函数的调用场景: 1.值传递传递函数体 2.值传递从函数体返回(返回匿名对象) 3.用 ...

  2. 拷贝构造函数与深拷贝和浅拷贝

    拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它必须的一个参数是本类型的一个引用变量. 作用就是用来复制对象,在使用这个对象的实例来初始化这个对象的一个新的实例.类中可以存在多个拷贝构 ...

  3. C++拷贝构造函数、深拷贝、浅拷贝

    对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a=88; int b=a;  而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. ...

  4. 简述构造函数、拷贝构造函数、深拷贝浅拷贝、析构函数

    一.构造函数特点: 1.构造函数也是函数,其函数名和类名相同 2.构造函数无返回值 3.构造函数可以重载 4.构造函数创建对象时自动调用 注:当设计一个类时,如果没有手动实现一个构造函数,那么编译器会 ...

  5. C++基础-拷贝构造函数(深拷贝与浅拷贝)

    拷贝构造函数 是一种特殊的构造函数,用于在建立新对象时将已存在对象的数据成员值复制给新对象,即用一个已存在的对象初始化一个新建立的对象. 定义一个拷贝构造函数的一般形式: 类名 (类名 & 对 ...

  6. 深拷贝、浅拷贝和深赋值、浅赋值

    一.深拷贝与浅拷贝 由系统提供的默认拷贝构造函数的实现是浅拷贝,浅拷贝是简单地对成员变量逐个进行拷贝赋值,一般不需要用 户自定义浅拷贝构造函数,系统会提供默认的浅拷贝构造函数.但是有时系统提供的浅拷贝 ...

  7. C++ 拷贝构造函数 赋值构造函数

    关键字:   C++      默认拷贝构造函数的行为如下:  默认的拷贝构造函数执行的顺序与其他用户定义的构造函数相同,执行先父类后子类的构造.  拷贝构造函数对类中每一个数据成员执行成员拷贝(me ...

  8. 【C++】运算符重载2-深拷贝深赋值、前加加后加加的重载

    深拷贝.深赋值 我们首先通过下面这段代码来研究一下深拷贝和浅拷贝,区分一下什么时候需要我们自己来写拷贝构造函数和赋值运算符重载的函数. class Test {private:int m_a = 1; ...

  9. 拷贝构造函数 浅拷贝与深拷贝

    目录 拷贝构造函数 浅拷贝 深拷贝 拷贝构造函数 上一期中我们讲述了构造函数的相关内容,谈到构造函数在形式上有几种分类,即带参数的.不带参数的以及参数列表初始化的,还有一种传引用的构造函数,称为拷贝构 ...

最新文章

  1. mysql oracle 默认事务级别_oracle 默认的事务隔离级别
  2. ServletContext对象详解
  3. shell基础之if语句
  4. .NET Conf 2021 回顾
  5. es6 WeakSet
  6. 数据科学和人工智能技术笔记 三、数据预处理
  7. UML系列——OO Unit4分析和学期总结
  8. oracle和mysql使用区别大吗_Oracle和MySQL在使用上的区别
  9. oracle disk missing,oracle asm disk被格式化为ntfs文件系统
  10. 手机APP ~ MUI——创建页面方法
  11. 微信投票作弊神器的制作代码
  12. Face Recognition 库-人脸识别
  13. 电脑如何通过USB连接PPC手机上网
  14. 51单片机中断程序大全
  15. Oracle 多行显示在一行详解(listagg)
  16. oracle IF_Oracle实时同步大数据平台解决方案
  17. MTK6577+Android GPIO
  18. 配置console口认证(华为/思科)
  19. java编写的音乐播放器
  20. java编程题目农夫果园_UML 农夫果园 小系统 设计模式

热门文章

  1. Java调用DLL对海关申报数据加签
  2. 基于webSocket的聊天室
  3. opencv-python +ski-image实现指静脉的LBP(局部二进制模式)特征提取
  4. 聊聊离线编程之生成轨迹那些事
  5. 基于Spring Boot应用@FunctionalInterface注解
  6. 中国十大“勾魂”美景-黄山云海
  7. java计算机毕业设计汽车维修管理系统源码+程序+lw文档+mysql数据库
  8. word论文排版和写作03:插入Origin作图--以点线图、柱状图和雷达图为例
  9. Android短信发送
  10. java动态加载js_动态加载JavaSript