深拷贝和浅拷贝

作者:greenpill
链接:https://www.nowcoder.com/discuss/168189
来源:牛客网

对于build-in类型来说,复制是简单的,都是开辟新的内存,将对应的值放入新开辟的位置即可,之后他们不再有关系(指针类型就是地址的复制,和指向的地方没关系)。
对于类而言,如果存在指针和引用类型,(const类型?),需要考虑自己来写拷贝构造函数和重载=操作符。

    • 浅拷贝(位拷贝)
      指将一个对象的内存映像按位原封不动的复制给另一个对象,所谓值拷贝就是指,将原对象的值复制一份给新对象。 在用"bitwise assignment"时会直接将对象的内存映像复制给另一个对象,这样两个对象会指向同一个内存区域,当一个对象被释放后,另一个对象的指针会成为野指针(悬垂指针)。这时,就应该编写operator=和copy constructor来实现值拷贝 。
      默认的拷贝构造函数”和“缺省的赋值函数”均采用“位拷贝”而非“值拷贝”的方式来实现,倘若类中含有指针变量,这两个函数注定将出错。

    • 深拷贝(值拷贝)
      在“深拷贝”的情况下,对于对象中动态成员,就不能仅仅简单地赋值了,而应该重新动态分配空间。

    • 产生复制的场景:

      1. 建立一个新对象,并用另一个同类的已有对象对新对象进行初始化
      2. 当函数的参数为类的对象时,这时调用此函数时使用的是值传递,也会产生对象的复制
      3. 函数的返回值是类的对象时,在函数调用结束时,需要将函数中的对象复制一个临时对象并传给改函数的调用处

      这里通过查资料存疑, 默认拷贝构造函数基本工作原理:对所有的非POD类型成员变量执行拷贝构造,POD类型成员变量则进行位拷贝,当成员变量都是POD类型的时候,编译器也许不会产生拷贝构造函数,只是对对象进行位拷贝。 默认operator=基本工资原理:对所有的非POD类型成员变量执行operator=操作,POD类型成员变量则进行位拷贝,当成员变量都是POD类型的时候,编译器也许不会产生operator=,只是对对象进行位拷贝。 从上面两个工作原理看到: 1.当class成员变量是有const修饰、引用类型、不能够提供operator=操作(例如boost::nocopyable)时候就不会产生operator=,我们对这个class对象进行赋值操作的时候就是编译出错。 2.当class成员变量是不能够提供拷贝构造操作(例如boost::nocopyable)时候就不会产生拷贝构造函数,我们对这个class对象进行拷贝构造操作的时候就是编译出错。 以前(2005年前?)c++各种参考文献对构造、析构和拷贝关注较多的是“深拷贝”和“浅拷贝”问题,现在的c++可能考虑更多的是如何保证不被拷贝^_^(个人见解)。

posted @ 2019-10-06 19:44  一日一更  阅读(225)  评论(0编辑  收藏  举报