小结一下在看《effective C++》的时候,收获的东西。
目录:
- 为什么在构造函数和析构函数里面不能调用虚函数?
- 析构函数能不能抛出异常?
- C++ 的对象返回机制
1.为什么在构造函数和析构函数里面不能调用虚函数 ?
因为在派生类创建对象的时候,首先会调用基类的构造函数,然后才调用自己的。如下所示:
class Base {
public:
Base() {
cout << "base" << endl;
print();
}
virtual void print() {
cout << "base print" << endl;
}
};
class derived :public Base {
public:
derived() {
cout << "derived" << endl;
}
virtual void print() {
cout << "derived print" << endl;
}
};
int main()
{
{
derived d;
}
return 0;
}
这样在基类的构造函数里面调用虚函数,那么在创建派生类的时候,首先会调用基类的构造函数。然后执行基类的print函数。因此,这样的设计没有意义。
ps:
创建派生类对象构造函数调用的顺序:基类 --> 派生类
析构派生类对象析构函数调用的顺序:派生类 --> 基类
2. 析构函数能不能抛出异常?
可以,但是最好这个异常可以在析构函数里面处理掉。
3. C++的对象返回机制
c++ 在函数里面返回一个对象的时候,需要调用两次拷贝构造函数。 第一次的时候,是把它拷贝到栈上面的临时对象上面。第二次是把临时对象拷贝到main函数上面的返回值上面。
class obj{
};
obj return_obj(){
return_obj = obj();
return return_obj;
}
int main(){
obj o=return_obj();
}
这样带来的一个问题就是,返回一个对象的开销比较大。所以,在尽可能的情况下面,返回一个对象的引用。(引用的对象不能是局部变量的引用)。
另外,c++提出一个RVO(RETURN VALUE OPTIMIZATION 返回值优化),可以将某些场合对返回对象的拷贝降低一次。直接将对象构造在传出时使用的临时对象上。因此,可以减少一次复制的过程。