Chinaunix首页 | 论坛 | 博客
  • 博客访问: 300115
  • 博文数量: 94
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 202
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-08 20:07
文章分类

全部博文(94)

文章存档

2017年(19)

2016年(30)

2015年(12)

2014年(33)

我的朋友

分类: LINUX

2017-05-24 16:30:33

1. 值传递通常要比引用传递的代价昂贵得多。例如下面例子,


点击(此处)折叠或打开

  1. class Person {
  2. public:
  3.     Person();
  4.     virtual ~Person();
  5.     //...

  6. private:
  7.     std::string name;
  8.     std::string address;
  9. };

  10. class Student: public Person {
  11. public:
  12.     Student();
  13.     ~Student();
  14.     //..

  15. private:
  16.     std::string schoolName;
  17.     std::string schoolAddress;
  18. };

  19. //consider codes bellow, what will happen?

  20. bool validateStudent(Student s);
  21. Student plato;
  22. bool platoIsOK = validateStudent(plato);


毫无疑问, Student的copy构造函数将被调用,以plato为蓝本将s进行初始化。当validateStudent返回s会被销毁。此种模式总共分别有6次构造和析构函数的调用(Student,Person,4个String)。

倘若以引用传递  

bool validateStudent(const Student& s);

这种方式的效率要高得多:没有任何构造函数或析构函数被调用,因为没有新对象被创建。所以const限制了对象不能被修改。


2. by reference方式传递参数也可以避免对象切割问题

当一个derived类对象以by value方式传递并被视为一个base类对象,base class基类的copy构造函数会被调用,而“derived class对象特性”将被切割,仅仅留下一个基类对象。


点击(此处)折叠或打开

  1. class Window {
  2. public:
  3.     //...
  4.     std::string name() const;
  5.     virtual void display() const;
  6. };

  7. class WindowWithScrollBars: public Window {
  8. public:
  9.     //...
  10.     virtual void display() const;
  11. };

  12. void printNameAndDisplay(Window w) //错误, 参数可能被切割
  13. {
  14.     std::cout << w.name();
  15.     w.display();
  16. }

  17. WindowWithScrollBars wwsb;
  18. printNameAndDisplay(wwsb);


以上函数参数w是Window的对象,是pass by value。而wwsb是
WindowWithScrollBars对象,传入后所有类WindowWithScrollBars的特性化信息都被丢失。因此,这里的wwsb被完全看作一个Window对象,其内部调用的

Window::display()而不是WindowWithScrollBars::display()。


为解决切割问题,需使用by reference to const的方式传递w:


点击(此处)折叠或打开

  1. void printNameAndDisplay(const Window& w) //很好! 参数不会被切割
  2. {
  3.     std::cout << w.name();
  4.     w.display();
  5. }


现在,传进来的窗口是什么类型,w就表现出哪种类型。


**尽量以pass-by-reference-to-const替换pass-by-value。通常前者高效,且可避免切割问题。

**以上规则并不适用于内置类型,以及STL的迭代器和函数对象。对这些而言,pass-by-value往往比较合适。




阅读(2485) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~