注意类类型的拷贝行为

来源:互联网 发布:python idle 位置 pyw 编辑:程序博客网 时间:2024/06/06 20:14

       当一个类被拷贝时,会面临许多的问题,其中之一就是对于一个类所拥有的资源能否被复制的问题。比如,自己要创建一个智能指针类型的类,那么对于这个类的拷贝初始化怎么办呢,如果直接赋值指针,那会造成非常严重的后果,这显然是不可取的。那么我们该怎么做呢,在effective中有四种方法禁止不合理的拷贝行为。

       1.禁止赋值:当自定义的类对象被复制并不合理的时候,那么可以将copying操作声明为禁止的,在c++11中,可以直接令copying函数为=delete,在老版本的编译器环境下,可以把相关函数定义为private的,来阻止用户使用。

       2.对底层资源使用“引用计数法”:即我们可以使用智能指针,来管理自己定义类中的底层资源,当底层资源被不在被需要时,会自动释放,当底层资源引用计数不为零时被保留。并且,类不用再实现析构函数,因为当调用析构函数时会自动调用非静态成员的析构函数,而对于智能指针,会自动调用其析构函数释放相应的底层资源。    注:使用share_ptr的好处不止在于引用计数,还在于可以自定义“删除器”,在构造是传入一个函数对象即可。(关于删除器不明白的可以参考相关书籍或者提问)

       3.复制底部资源:即所谓的深复制。

       4.转移底部资源的拥有权:在c++11的新标准中,资源的拥有权会从被复制物转移到目标物,即所谓的移动构造函数和移动赋值函数。而在新标准中对于一个右值,由于其特性是即将销毁并且没有其他的使用者,所以对一个右值使用移动操作是安全且合法的,而对于一个左值要进行移动操作则需要调用std::move()函数强制生成一个右值引用,而当你调用move时意味着承诺和责任,即你所引用的那个左值是不能在被使用,且其在被移动后是处于安全可销毁状态的。在老标准中,由于没有右值移动,所以可以在需要实现移动的类中自己编写移动代码,其行为类似auto_ptr。但是这意味着你必须保证其指挥使用到移动代码,因为,其移动操作也是在拷贝构造函数中使用的,所以其将不存在拷贝操作。所以本方法仅仅在非常罕见的情况下适用。

       拷贝行为会被编译器自动创建出来,即所谓的缺省行为。如果缺省的行为不能满足你的要求,则你得自己编写他们!

所以类的资源的拷贝行为决定类对象的拷贝行为,这点必须牢记。