Constructors,Destructors,and Assignment Operators #
5.Know what functions C++ silently writes and calls #
-
编译器可以暗自为class创建default构造函数 、copy构造函数、copy assignment操作符,以及析构函数
区分copy构造和copy赋值
class Widget{ public: Widget();//default构造 Widget(const Widget& rhs);//copy构造 Widget& operator=(const Widget& rhs);//copy assignment操作符 }; Widget w1;//default构造 Widget w2(w1);//copy构造 w1 = w2;//copy assignment操作符 Widget w3 = w2;//copy构造 通过是否真正产生新的对象来区分copy构造和拷贝赋值
6.Explicitly disallow the use of compiler-generated functions you do not want #
-
所有编译器产出的函数都是public,为驳回编译器自动提供的机能,可将相应的成员函数声明为Private并且不予实现
#define Q_DISABLE_COPY(Class) \ Class(const Class &) = delete;\ Class &operator=(const Class &) = delete;
class Uncopyable { protected://允许derived对象构造和析构 Uncopyable(){} ~Uncopyable(){} private: Uncopyable(const Uncopyable&); Uncopyable& operator=(const Uncopyable&); } //继承Uncopyable可以阻止HomeForSale对象被拷贝 class HomeForSale:private Uncopyable { ... }
7.Declare destructors virtual in polymorphic base classes #
-
只有当class内含至少一个virtual函数才为它声明virtual析构函数
-
标准string和STL窗口都不被设计作为base classed使用,因为它们的析构函数都不带virtual
8.Prevent exceptions from leaving destructors #
-
析构函数绝对不能抛出异常
-
通常通过调用abort结束程序,来阻止异常从析构函数传播出去
DBConn::~DBCOnn()
{
try{
db.close();//可能抛出异常
}
catch(...){
std::abort();
}
}
9.Never call virtual functions during construction or destruction #
禁止在构造函数和析构函数中调用virtual函数,并且在它们调用的所有函数也都服从这一约束,因为此时derived class的成员变量处于未定义的状态
class Transaction{
public:
Transaction();
virtual void logTransaction() const = 0;
}
Transaction::Transaction()
{
...
logTransaction();//错误,构造和析构中禁止调用虚函数
}
class BuyTransaction:public Transaction{
public:
virtual void logTransaction() const = 0;
}
10.Have assignment operators return a reference to *this #
让赋值assignment操作符返回一个reference to *this
class Widget{
public:
Widget& operator+=(const Widget& rhs)
{
...
return *this;
}
Widget& operator=(int rhs)
{
...
return *this;
}
}
11.Handle assignment to self in operator= #
Widget& Widget::operator=(const Widget& rhs)
{
if(this == &rhs)
return *this;
delete pb;
pb = new Bitmap(*rhs.pb);
return *this;
}
12.Copy all parts of an object #
Copying函数应该确保复制对象内的所有成员变量及所有base class成分
//调用所有base classes内的适当的copying函数
class PriorityCUstomer::PriorityCUstomer(const PriorityCustomer& rhs)
:Customer(rhs),//调用base class的copy构造函数
priority(rhs.priority)
{
}
//不该令copy assignment操作符调用copy构造函数,也不在copy构造函数调用copy assignment操作符
PriorityCUstomer& PriorityCUstomer::operator=(const PriorityCUstomer& rhs)
{
Customer::operator=(rhs);//调用base class的赋值动作
priority = rhs.priority;
return *this;
}