C++学习笔记11——复制控制

来源:互联网 发布:手机淘宝申请退款 编辑:程序博客网 时间:2024/06/05 22:52

复制构造函数是一种特殊构造函数,具有单个形参,并且该形参是对该类类型的引用,在定义一个新对象并用一个同类型的对象对他进行初始化时,将显式调用复制构造函数。当将该类型的对象传递给函数或从函数返回该类型的对象时,将隐式使用赋值构造函数。

在对象超出作用域或动态分配的对象被删除时,将自动应用析构函数。析构函数主要用于释放对象时构造或在对象的生命期中所获取的资源。

复制初始化使用=符号,总是要调用复制构造函数,首先使用指定构造函数创建一个临时对象,然后用复制构造函数将临时对象复制到正在创建的对象。

形参、返回值为非引用类型是,将会复制其值;即当其为非引用类类型时,由复制构造函数进行复制。

合成的复制构造函数即由编译器自动生成的,其行为是逐个成员初始化,将新对象初始化为原对象的副本。逐个成员就是编译器将现有的每个非static成员,依次复制到正创建的对象。

赋值构造函数就是接受单个类类型引用形参(通常const修饰)的构造函数。对于含有指针数据成员或者有成员表示在构造函数中分配的其他资源、或者在创建新对象时要完成其他的一些特定工作,都需要定制构造函数。

为了完全禁止复制,可以声明一个private复制构造函数但不对其定义。

某类型对象赋值时,会使用赋值操作符。合成的赋值操作符执行逐个成员赋值,除了数组之外,每个成员所属类型的常规方式进行赋值,而数组则是对每个元素赋值。

在撤销类对象会自动调用析构函数,动态分配的对象只有在指向该对象的指针被删除时才撤销。

一般情况下,如果类需要析构函数,则它也需要复制操作符和复制构造函数。

与复制构造函数和赋值操作符不同,编译器总是会合成一个析构函数,合成析构函数按对象创建时的逆序撤销每个非static成员,即在按成员在类中声明次序的逆序撤销成员。析构函数是个成员函数,它的名字是在类名字之前加上一个“~”字符,他没有返回值,也没有形参,所以不能重载析构函数。并且即使我们编写了自己的析构函数,合成析构函数仍然运行。

对于具有指针成员的类时,需要对指针进行管理:

1、  指针采取常规指针行为,也就跟普通的指针相同。当一个指针复制到另一个指针时,两个指针指向同一个对象。

2、  类可以实现所谓的“智能指针“行为。指针所指向的对象是共享的,但类能够防止悬垂指针。其能够保证撤销指向对象的最后一个对象时删除对象。为达到此目的,我们引入使用计数,将一个计数器与类指向的对象相关联,当使用计数为0时,删除对象。每创建对象,初始化指针并使用计数置为1,当对象作为另一个对象的副本创建时,复制构造函数复制指针并增加使用计数的值。对一个对象进行赋值时,赋值操作符减少左操作数所指向对象的使用计数的值,并增加右操作数所指对象的使用计数的值。最后调用析构函数,析构函数减少使用计数的值,为0时删除对象。

可以单独定义一个类用以封装使用计数和相关指针,并在类中保存一个指向这个封装类的指针。

3、  类采取值型行为,指针所指向的对象是唯一的,由每个类对象独立管理。给指针提供语义,具有语义的类所定义的对象,在复制对象时,会得到一个不同的新副本。这时,复制构造函数初始化对象以保存与被复制对象相同的值。赋值操作符不分配新对象,而是给其指针所指向的对象赋新值。