Effective C++读书笔记之宁以pass-by-reference-to-const替换pass-by-value

 我们用pass-by-reference-to-const替换pass-by-value主要是有两个方面的考虑:
 1) 效率问题
 缺省情况下C++以by value方式传递对象。除非你另外指定,否则函数参数都是以实际实参的复件(副本)为初值,其返回值也是一个复件。这些复件由对象的copy构造函数产出。因此pass-by-value是一个费时操作。例如:
 class Person {};
 class Student : pbulic Person { };  //学生类
 现在有一个函数:
 bool validateStudent(Student s);   //函数以by value方式接受学生
 student plato;
 bool platoIsOk = validateStudent(plato);  //调用函数
 上面的传值会全Student的构造函数会被调用,以plato初始化s,同时在函数结束时,s会被销毁。不仅如此Student类中的所有数量成员的copy构造函数以及基类中的所有成员的构造函数也都会被调用,在销毁时,针对每一个构造函数还要调用相应的析构函数。这造成了巨大的开销。所以我们可以使用pass-by-reference-to-const替换pass-by-value。如下:
 bool validateStudent(const Student& s);   //函数以by-reference-to-const方式接受学生
 这种传递效率高多了,没有任何的构造函数和析构函数被调用,因为没有任何的对象被创建。注意这里使用了const,在by value时如果修改发生,修改的是副本,原来数据没有变化。为了使by-reference时原来数据不会被修改,必须使用const来修饰。
 2) by value可能造成对象分割(slicing)
 当一个derived class对象以by value方式传递并被视为一个base class对象,base class的copy构造函数会被调用,这只会构造一个base class对象。而derived class中独有的特性全部被丢掉了。例如:
 class Window {
 pbulic:
  ....
  string name() const;            //返回窗口名称
  virtual void display() const;   //显示窗口和其内容 是个virtual函数
 };
 class WindowWithScrollBars: pbulic Window {
 public:
  ....
  virtual void display() const;  
 };
 现在有一个函数:
 void printNameAndDisplay(Window w)   //参数可能被分割
 {
  w.display();
 }
 当你调用上面的函数,给它一个WindowWithScrollBars对象时,如下:
 WindowWithScrollBars wwsb;
 printNameAndDisplay(wwsb);
 由于是passed by value,所以参数会被构造成一个Window对象,不管你传给它是什么类型的对象。所以在函数调用display函数调用的总是Window::display,绝不会是WindowWithScrollBars::display。解决的方法就是以pass-by-reference-to-const的方式传递w。如下:
 void printNameAndDisplay(const Window& w)   //参数不会被分割
 {
  w.display();
 }
 实际这就实现了一个多态了。
 3) C++编译器对内置类型和自定义类型的不同处理
 一般而言,你可以合理的假设对内置类型和STL的迭代器和函数对象使用pass-by-value是好的,而对其它的自定义的类型最好是使用pass-by-reference-to-const。
 总结:
 1) 尽量以pass-by-reference-to-const替换pass-by-value,前者通常比较高效,并可避免切割(slicing problem) 
 2) 以上规则并不适用内置类型,以及STL的迭代器和函数对象,对它们而言pass-by-value往往比较适当

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值