• c++ 类中隐藏的六个(c11之后 八个)默认函数


    class Test
    {
    public:
    	Test();
    	~Test();
    	Test(const Test&);
    	Test& operator=(const Test&);
    	Test* operator&();
    	const Test* operator&()const;
    	Test(Test&&);
    	Test& operator=(Test&&);
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在c11之后,类中总共有8个默认函数,其中
    移动拷贝:Test(Test&&)
    移动赋值:Test& operator=(Test&&)
    都是在c11之后才新添加的。

    1.构造函数
    作用:
    1.给对象所在的内存空间做初始化,创建对象。
    2.类型转换
    特点:
    1.可以根据实际需要进行缺省的,或者重载
    2.不依赖对象,对象无法调用,只能在对象定义点调用

    2.析构函数
    1.不可重载,对象销毁时会调用析构函数,并释放空间
    2.依赖对象,可以通过this->~Test()来调用,但是不建议,如果手动调用最后可导致析构函数重复调用,导致程序崩溃。

    3.拷贝构造函数
    作用:拿一个已存在的对象再来生成相同类型的新对象。
    注意:类中默认提供的拷贝构造函数为浅拷贝构造,如果对象申请了系统资源的话,则需要我们自己重写它。

    4.赋值运算符重载函数
    作用:拿一个已存在的对象给一个已存在的该类型对象进行赋值
    实现步骤:
    浅拷贝的实现

    class Test
    {
    public:
    	Test(int value =0) :value_(value) {}
    	Test& operator=(const Test& test)
    	{
    		if (this != &test)
    		{
    			value_ = test.value_;
    		}
    		return *this;
    	}
    private:
    	int value_;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    深拷贝的实现:

    class Test
    {
    public:
    	Test(int value):value_(new int(value)){}
    	Test&  operator=(const Test& test)
    	{
    		if (this != &test)
    		{
    			delete value_;
    			value_ = nullptr;
    			value_ = new int(*(test.value_));
    		}
    		return *this;
    	}
    private:
    	int* value_;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    1.自赋值判断 防止是自己给自己赋值,假如说是自己给自己赋值的话,如果没有这一步判断,我们按照上面的代码走,先delete value_,然后再执行到new int(*(test.value_));时,此时要解引用test的value_,此时因为已经为nullptr,此时就会程序崩溃。
    2.释放旧资源
    3.生成新资源
    因为对象申请了系统资源,所以需要深拷贝,此时对新对象也要申请系统资源。
    4.赋值

    注意:
    为什么要以引用返回
    1.为了更好的拟合内置类型。
    c++是由四部分组成:1.c,2.c++的对象特性,3.template c++,4.STL,所以对于c++来说,也要拟合于c,即意思是,尽可能的贴近或者模仿它的内置类型,比如当我们使用int时,定义三个int 变量a,b,c,当我们进行a=b=c;时,实际是通过c这个对象本身赋值给b,然后通过b这个对象本身赋值给a,赋值的时候并没有产生匿名对象。
    2.为了减少一个匿名对象的构造,效率更高

    好多人说为什么要以引用而不是值返回的时候,说的是使用引用的话可以实现 a=b=c这种连等,但实际是,当我们以值返回时也可以达到这种目的
    当我们以值返回时,生成一个匿名对象(将亡值),接着由这个匿名对象对其赋值b赋值(调用的是b的赋值重载),对a也是同理的。
    在这里插入图片描述

    5.一般对象取地址函数

     Test* operator()
     {
       retrun this;
    }
    
    • 1
    • 2
    • 3
    • 4

    6.常对象取地址函数

    const Test* operator&()const
    {
    	return this;
    }
    
    • 1
    • 2
    • 3
    • 4

    7.移动拷贝
    作用:把一个对象的资源转移给另外一个对象,减少了对资源的扰动(对资源的释放又申请)
    使用场景:把将亡值对象的资源继续给其它对象使用。

    Test (Test&& test):value_(test.value_)
    	{
    		test.value_ = nullptr;
    	}
    
    • 1
    • 2
    • 3
    • 4

    8.移动赋值
    作用:把一个对象的资源转移给另外一个对象,减少了对资源的扰动(对资源的释放又申请)

    Test& operator=(Test&& test)
    	{
    		if (this != &test)
    		{
    			value_ = test.value_;
    			test.value_ = nullptr;
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    【计算机组成原理】第三章单元测试
    你不知道的大像素全景,在行业应用中竟如此重要
    数据结构与算法-树论基础&二叉树
    密度聚类与层次聚类
    DockerFile解析
    Python自定义排序及实际遇到的一些实例
    27 - Excel 的基本公式和重要函数
    SkyWalking告警通知
    DC-6靶场下载及渗透实战详细过程(DC靶场系列)
    Ceph入门到精通-Macvlan网络模式
  • 原文地址:https://blog.csdn.net/aoeaoao/article/details/127788004