admin 管理员组

文章数量: 1184232


2024年5月21日发(作者:c语言冒泡法降序排列)

对待拷贝构造函数和赋值函数的3种境界

2010-10-29 11:53 by zhenjing, 817 visits, 网摘, 收藏, 编辑

对待拷贝构造函数和赋值函数有3种境界:不写;禁用;正确编写。

1) 不写。不写代码是编程的最高境界。有一种说法:最完美的代码是无以复减的代

码。不写的代码永远不会出错,也不需要维护。任何存在的代码都需要维护,只要代码可能

变化。

C++的编译器可以提供默认的构造函数、析构函数、拷贝构造函数、赋值函数、一对

取址运算符(*, &)。C++的默认构造函数仅对内置变量随机赋值,具有不确定性,一般不建

议使用默认构造函数;对于析构函数讨论比较多,这里不加讨论。但有一个准则:如果需要

编写任一特定的析构函数、拷贝构造函数或者赋值函数,那么你也需要编写其余的两个。

何时不写呢?只要类(包括类中的类变量)不拥有任何资源,那么就可利用编译器的默认

版本。常见资源有:内存、文件和端口。任何资源都需要显式的获取和释放,C++的默认

拷贝和赋值操作并无法保证正确的资源获取和释放。

如果直接使用编译器版本,最好加注释,让代码阅读者更清楚。

2)禁用。禁用代码将给代码的使用者明确的提示,防止误用。如果你定义的类,并不

需要拷贝和赋值,请明确禁用,而不是让使用者误用编译器提供的错误版本。示例:

class T {// …

private: // make T non-copyable

T( const T& ); // not implemented

T& operator=( constT& ); // not implemented

};

3)巧妙正确地写。只要类拥有自己的资源,用户都需要自行编写拷贝构造函数和赋值

函数,或者直接禁止(直接使用对象指针或引用,这样的类不具有值属性)。代码示例:

代码

#include #include using namespace std;template

T> class NamedPtr{public: explicitNamedPtr(const std::string& name);

//NamedPtr(conststd::string& name, T *data); //note:user manages the memory

~NamedPtr(); NamedPtr(constNamedPtr& rhs);

NamedPtr&operator=(const NamedPtr& rhs); voidPrint() const;private:

std::stringm_name; T*m_data; // can be T or T[]. Atthis example use T

only};templateNamedPtr::NamedPtr(conststd::string& name):

m_name(name), m_data(NULL){ m_data= new T(); // T must have a

defaultconstructor}//template

T>//NamedPtr::NamedPtr(conststd::string&

m_name(name)//,

name, T *data)//:

m_data(data)//{//}template

T>NamedPtr::~NamedPtr(){ deletem_data; m_data=


本文标签: 代码 赋值 需要 拷贝 函数