c++坑之拷贝函数总结

C++构造函数


  1. c++类的中有两个特殊的构造函数(都是构造函数)
    (1)无参构造函数
    (2)拷贝构造函数classname (const classname &obj)(默认的拷贝构造函数—常引用型,拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它必须的一个参数是本类型的一个引用变量)

  2. 它们的特殊之处在于:
    (1)当类中没有定义任何构造函数时,编译器会默认提供一个无参构造函数且其函数体为空;
    (2)当类中没有定义拷贝构造函数时,编译器会默认提供一个拷贝构造函数,进行成员变量之间的拷贝。(这个拷贝操作是浅拷贝)

注意:也就是说,构造函数包含拷贝函数,如果定义了一个拷贝函数,就没有默认的构造函数了

拷贝函数的使用时机

当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用。也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:

  • 一个对象以值传递的方式传入函数体
  • 一个对象以值传递的方式从函数返回
  • 一个对象需要通过另外一个对象进行初始化
  • c++STL容器也是调用拷贝构造函数

深拷贝和浅拷贝

1.深拷贝是为指针分配了地址(比如为其new了一个新的)而浅拷贝只是赋值---pr1=pr2,此时浅拷贝两个的对象的某个属性的指针指向同一块地址。(图:浅拷贝,深拷贝)
浅拷贝
深拷贝

深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝

等号运算符与拷贝函数

1
2
3
4
5
6
7
如果对象在申明的同时马上进行的初始化操作,则称之为拷贝运算。例如:
class1 A("af"); class1 B=A;
此时其实际调用的是B(A)这样的浅拷贝操作。
如果对象在申明之后,在进行的赋值运算,我们称之为赋值运算。例如:
class1 A("af"); class1 B;
B=A;
此时实际调用的类的缺省赋值函数B.operator=(A);

等号运算符类似浅拷贝,所以,class有指针,不仅一定要重写拷贝构造函数(写深拷贝),还要重载=运算符8

##NOTE

  1. 尽量避免值传递,最好用指针和引用.如果对象有内部指针指向动态分配的堆内存,丝毫不要考虑把对象按值传递给函数,要按引用传递。并记住:若函数不能改变参数对象的状态和目标对象的状态,则要使用const修饰符
  2. 对于类的成员需要动态申请堆空间的类的对象,大家都知道,我们都最好要overload其赋值函数和拷贝函数。拷贝构造函数是没有任何返回类型的,这点毋庸置疑。 而赋值函数可以返回多种类型,例如以上讲的void,类本身class1,以及类的引用 class & (可以实现连等)

参考两篇很好的博客博客2

© 2020 WPY's Android Tour All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero