C++ 三个特殊函数:拷贝构造、拷贝赋值、析构

看的侯捷老师的课

用的string作为讲解

以上是老师给出了简单的string实现,

String s3(s1);  //这里s3第一次出现,是拷贝构造
...
s3 = s2; //这里s3要被赋值,调用的是不一样的函数

复数也存在拷贝构造和赋值,但是之前的课没有讲到,因为编译器会自动一个bit一个bit这样的copy,复数只有实部和虚部,没有指针,所以默认的够用。

但string类的包含有指针,编译器默认的则不够用,默认的话,拷贝的对象和原对象,它们的指针会指向相同的地址,这不是我们想要的结果。

括号内为自己写的构造函数,拷贝构造函数等,

其中

String(const char* cstr = 0); //构造
String(const String& str); //拷贝构造
String& operator=(const String& str);//拷贝赋值
~String(); //析构

构造函数,默认指针为空指针,初始化时,若未指定值,则给*m_data一个结束符号,

若给定初值,strlen(cstr)给的值是不包含'\0'的长度,因此分配长度加一,用来放置结束符。

析构函数离开作用域后会调用的函数。        

 因为使用new做了动态分配,分配了一块内存给“hello\0”存储,所以要delete将这块内存释放掉

类如果有指针成员,则一定要有拷贝构造和拷贝赋值!

没有的话,下图很好的体现了问题

"World\0"没有指针指向它,内存泄露了,

而"Hello\0"两个指针指向它,则一个改动,另一个也受影响。alias 别名,危险操作。

这种情况就是浅拷贝

我们要做的就是实现深拷贝

拷贝构造函数

传进参数,传入引用,且蓝本str不改动,所以加上const

拷贝构造函数的参数如果是普通传值类型,而非引用,会引发无限递归最终导致崩溃

这里引用知乎上看到的

        复制构造函数,其实也是一个函数,如果你给它定义的参数,是一个类型,而不是一个类型的引用,它会首先调用该类型的复制构造函数,重新构造一个新的实例。

那么新的实例创建也会继续调用拷贝构造,则会无限递归。

拷贝构造要创建出足够的空间来存放蓝本str

String s1("hello ");
String s2(s1);
//String s2 = s1;

这里老师提到,当s2都是没出现时,两种方式起到的作用完全相同,都是调用拷贝构造函数。

拷贝赋值函数

要把右边的对象赋值到左边的对象上,则应该先清空左边的对象,再创建跟右边一样大的空间,然后把右边拷贝到左边。

自我赋值,会发生,但是有时候看起来不像,所以要检测。这样效率高,更关键是避免如下图情况

,保证了正确性。

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值