effective C++ 第五章
2011-11-20 15:57 Clingingboy 阅读(531) 评论(0) 编辑 收藏 举报
第五章:实现
条款 27:尽量少做转型动作
1.转换一个explicit构造函数
class Widget {
public:
explicit Widget(int size);
...
};
void doSomeWork(const Widget& w);
doSomeWork(Widget(15)); // create Widget from int
// with function-style cast
doSomeWork(static_cast<Widget>(15)); // create Widget from int
// with C++-style cast
2.不要在子类中转换基类调用(调用了一个副本对象)
class Window { // base class
public:
virtual void onResize() { ... } // base onResize impl
...
};
class SpecialWindow: public Window { // derived class
public:
virtual void onResize() { // derived onResize impl;
static_cast<Window>(*this).onResize(); //wrong cast *this to Window,
Window::onResize();//right
// then call its onResize;
// this doesn't work!
... // do SpecialWindow-
} // specific stuff
...
};
3.dynamic_cast的替代方案
(1)直接使用子类,避免转型…貌似废话
之前:
class Window { ... };
class SpecialWindow: public Window {
public:
void blink();
...
};
typedef // see Item 13 for info
std::vector<std::tr1::shared_ptr<Window> > VPW; // on tr1::shared_ptr
VPW winPtrs;
...
for (VPW::iterator iter = winPtrs.begin(); // undesirable code:
iter != winPtrs.end(); // uses dynamic_cast
++iter) {
if (SpecialWindow *psw = dynamic_cast<SpecialWindow*>(iter->get()))
psw->blink();
}
之后:
typedef std::vector<std::tr1::shared_ptr<SpecialWindow> > VPSW;
VPSW winPtrs;
...
for (VPSW::iterator iter = winPtrs.begin(); // better code: uses
iter != winPtrs.end(); // no dynamic_cast
++iter)
(*iter)->blink();
2.在基类使用虚函数
3.避免在循环中大量使用dynamic_cast
条款 29:为“异常安全”而努力是值得的
提供三种异常保证:
1.基本承诺:如果异常被抛出,程序内的任何事物仍保持在有效状态下。
2.强烈保证:要么成功,要么失败。保持执行前后状态一致(通常以copy-and-swap实现)
3.不抛掷保证:承诺绝不抛出异常。
大部分函数都属于连带影响,所以很难道做到强烈保证,不抛掷保证也是如此,一旦函数复杂了,有连带影响就会如此.所以只能尽量提供基本承诺,并提供异常码.
每个函数都处理异常是一个很繁琐的处理.
条款 31:将文件间的编译依存关系降至最低
很常用的声明和定义分离开发,即每份代码都有一个接口声明和一份代码实现,个人不大喜欢这样.没必要每份代码都遵守这个规则,太死板了吧.