6、条款09: 绝不在构造和析构过程申调用virtual函数
-
base class 构造期间virtual 函数绝不会下降到derived classes阶层。取而代之的是,对象的作为就像隶属base类型一样。
-
非正式的说法或许比较传神:在baseclass构造期间,virtual函数不是virtual函数。
-
由于base class 构造函数的执行更早于derived class构造函数,当base class构造函数执行时derived class的成员变量尚未初始化。
-
在derived class对象的base class构造期间,对象的类型是base class 而不是derived class。
-
不只virtual 函数会被编译器解析至(resolve to) base class,若使用运行期类型信息(runtime type information,例如dynamic_cast(见条款27) 和typeid) ,也会把对象视为base class类型。
7、条款10: 令operator= 返回一个reference to *this
8、条款11: 在operator= 中处理"自我赋值"
9、条款12: 复制对象时勿忘其每一个成分
任何时候只要你承担起"为derivedclass撰写copying函数"的重责大任,必须很小心地也复制其baseclass成分。那些成分往往是private(见条款22) ,所以你无法直接访问它们,你应该让derivedclass的copying函数调用相应的baseclass函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
PriorityCustomer::PriorityCustomer(constPriorityCustomer& rhs)
: Customer(rhs),
//调用baseclass的copy构造函数
priority(rhs.priority)
{
logCall(
"PriorityCustomer copy constructor"
);
PriorityCustomer&
PriorityCustomer::operator=(constPriorityCustomer& rhs)
{
logCall(
"PriorityCustomer copy assignment operator"
);
Customer::operator=(rhs);
//对baseclass成分进行赋值动作
priority= rhs.priority;
return
*
this
;
}
|
编写一个 copying函数,请确保
(1) 复制所有local 成员变量,
(2) 调用所有base classes 内的适当的copying函数。
-
不该令copy assignment操作符调用copy构造函数。
-
反方向一一令copy构造函数调用copy asssignment操作符一一同样无意义。
10、条款17: 以独立语句将newed对象置入智能指针
void processWidget(std::trl::shared_ptr<Widget>pw, int priority);
processWidget(new Widget, priority()); //不能通过编译
processWidget(std::trl::sharedptr<Widget>(new Widget), priority()); //编译可以通过
-
调用priority
-
执行"newWidget"
-
调用trl::sharedytr构造函数
C++编译器以什么样的次序完成这些事情呢?弹性很大,所以调用过程中可能引发资源泄漏,因为在"资源被创建(经由"new widget")"和"资源被转换为资源管理对象"两个时间点之间有可能发生异常干扰。
使用分离语句即可避免。
std::trl::sharedptr<Widget> pw(new Widget); //在单独语句内以智能指针存储newed所得对象。
processWidget(pw, priority()); //这个调用动作绝不至于造成泄漏。
-
以独立语句将newed对象存储于(置入)智能指针内。如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏。