《Effective C++ 中文版 第三版》读书笔记
条款 20:宁以 pass-by-reference-to-const 替换 pass-by-value
一个例子:
class Toby{
public:
...
std::string name() const;
virtual void display() const;
};
class Son: public Toby{
public:
...
virtual void display() const;
};
如果此时有个打印窗口名称的函数,像这样:
void printNameAndDisplay(Toby t){
std::cout<<t.name();
t.display();
}
当你调用上面方法,并传递给他一个 Son 的对象时,会发生什么呢?
Son tS;
printNameAndDisplay(ts);
参数 t 会被构造成为一个 Toby 对象;因为他是 passed by value,还记得么?而保证 tS “之所以是个 Son 对象” 的所有特征化信息都会被切除。在 printNameAndDisplay 函数内不论传递过来的对象原来是什么类型,参数 t 就像一个 Toby 对象(因为其类型就是 Toby)。因此 printNameAndDisplay 内调用 display 调用的总是 Toby::display,绝不会是 Son::display。
解决这种切割问题的办法就是以 by-reference-to-const 的方式传递 t;
void printNameAndDisplay(const Toby& t){
std::cout<<t.name();
t.display();
}
现在,传进来的窗口是什么类型,t 就表现出那种类型。
一般而言,你可以合理假设 “pass-by-value 并不昂贵” 的唯一对象就是内置类型和 STL 的迭代器和函数对象。至于其他任何东西都请遵守:尽量以 pass-by-reference-to-const 替换 pass-by-value。
** 请记住: **
- 尽量以 pass-by-reference-to-const 替换 pass-by-value。前者通常比较高效,并且可以避免切割问题。
- 以上规则并不适用于内置类型,以及 STL 的迭代器和函数对象。对他们而言,pass-by-value 往往比较适当。
网友评论