使用pass-by-reference-to-const而不是pass-by-value

默认情况下,C++以传值(by-value)的方式传递对象至函数。
而C++也提供一种by-reference的方式。
那么,两者有什么去别呢?或者说,by-reference有什么好处吗?

性能问题

这些副本由对象的拷贝构造函数产出,这可能是pass-by-value费时的原因。
考虑一下代码。

class Person
{private:/* data */string name;string address;public:Person(/* args */){cout << "Person ctor" << endl;}virtual ~Person() // 这里一定要有virtual{cout << "Person dtor" << endl;}
};class Student : Person
{private:/* data */string schoolName;string schoolAddress;public:Student(/* args */){cout << "Student ctor" << endl;}~Student(){cout << "Student dtor" << endl;}
};bool validateStudent(Student s)
{return true;
}

当前的validateStudent函数会执行6次拷贝构造函数和6次析构函数,
分别是Person、Student和4个string。

而通过引用的方式没有任何构造函数和析构函数被调用。

bool validateStudent(const Student& s);

现在以pass-by-reference的方式进行调用时,将它声明为const是很有必要的,因为pass-by-value的时候调用者知道传入的是一份copy,不会对原来的Student对象产生任何改变,因为不这样做的话,传入reference会引起调用者的担心。

对象切割(Slicing)问题

现有代码

class Window
{private:/* data */string _name;
public:string name() const{return _name;}virtual void display() const{cout << "simple window" << endl;}Window(): _name("Window") {}~Window() {}
};class WindowWithScrollBar : public Window
{private:/* data */
public:virtual void display() const{cout << "window with scrollbar" << endl;}WindowWithScrollBar() {}~WindowWithScrollBar() {}
};

若传参方式是by-value

void printNameAndDisplay(Window w)
{cout << w.name() << endl;w.display();
}

那么将会产生对象切割问题,即使传入的是derived class对象,但是base class内的拷贝构造函数将会被调用,derived class内部的”特性“都会被切割掉。所以内部调用总是Windows::display()

总结

  1. 从C++编译器底层实现来看,reference往往是以指针实现,所以对内置类型而言,pass-by-value可能比pass-by-reference效率会高些。STL的迭代器和函数对象也适用此条。
  2. 内置类型都很小,于是所有小型的class都适用pass-by-value这是个不靠谱的推论
  3. 由于某些编译器对待内置类型和用户定义类型的态度截然不同。所以对于哪怕只有一个double成员的自定义类对象,也更应该以pass-by-reference的方式传递。

【Effective C++】item20: Prefer pass-by-reference-to-const to pass-by-value相关推荐

  1. Effective C++条款20解读:宁以pass by reference to const替换pass by value

    我们先来看一个简单的程序: #include <iostream> using namespace std;class A { private:string name;string add ...

  2. 【读书笔记】【Effective STL】容器

    第 1 条:慎重选择容器类型. C++ 中不同的容器分类如下:[标准 or 非标准][STL or 非 STL][序列 or 关联] 标准 STL 序列容器:vector.string.deque.l ...

  3. 【Effective C++】比较 pass-by-value 与 pass-by-referrence

    pass by what? 情况 -> 传值.传指针.传引用 总体:对于cpu寄存器来说,三种情况是一样的 传值:实际上是把值传递给了寄存器 传地址.传指针:实际上是把地址暴露给了寄存器 为什么 ...

  4. 【Effective Java】最佳实践 其他合集

    避免创建无用对象: 警惕自动装箱autoboxing Long sum = 0L; for(long i = 0 ; i < Integer.MAX_VALUE; i++) {sum += i; ...

  5. 【Effective Java】3.单例

    传统单例 private 构造函数 最优单例实现:使用Enum 1.无需担心序列化 先说说传统单例,其如果序列化再反序列化产生的效果和构造一个新的对象差不多的.除非增加以下来阻止: //readRes ...

  6. 【Effective Java】1.静态工厂方法来替换构造函数

    优点一:不像构造函数,它有具意的名称 因为可以取具意的名称,更容易明白如何使用,可读性也更好, 优点二:每次调用无需创建新的对象 优点三:允许返回子类对象 这些子类可以不为public ,这样可以打造 ...

  7. 【effective c++】继承与面向对象设计

    1.确定你的public继承塑造出is-a关系 public继承意味着is-a.适用于base classes身上的每一件事情一定也适用于derived classes身上,因为每一个derived ...

  8. 【Effective Java】6、使用复合优先于使用继承

    这个,不管是什么书都会这样说,因为常常我们并不需要继承,而只是想把类进行一定的扩展,而我们想扩展的属性或方法对应的类都有,这个时候如果两者是is a的关系,这种关系是确实存在的,那么就可以使用继承,不 ...

  9. 【Effective Java】第二章:静态工厂、构建器、强化Singleton属性、私有构造器、

    文章目录 一. 用静态工厂方法代替构造器 优势: 劣势: 实例代码: 二. 遇到多个构造器参数时要考虑使用构建器 ① 重叠构建器 ② JavaBeans模式 ③ Builder模式 三. 用私有构造器 ...

最新文章

  1. 图论 ---- E. Bear and Forgotten Tree 2(判补图的联通性技巧 图遍历的优化 条件拆分)
  2. java字符串,包,数组及空心正方形,菱形的实例
  3. python软件怎么用-如何使用Python自动控制windows桌面
  4. python 编程一日一练-Python每日一练0013
  5. windows环境下安装scrapy框架报错问题--最快捷有效的解决方案
  6. oracle数据库sysaux表空间,如何管理oracle数据库的SYSAUX表空间
  7. Some Essential JavaScript Questions And Answers(3)
  8. linux相关英文书记,Linux常用软件(英文介绍)
  9. oracle dg 备库未设置convert参数导致ORA-01111,ORA-01110
  10. 区分那些是属于构架方面的C++功能
  11. 如何向女朋友解释什么是HTTP协议
  12. 真正的研发之路(1)
  13. Java开发微信公众号
  14. Web全栈~02.表单样式设计
  15. vscode安装 Fira Code 编程字体,编程符号更精致美观
  16. Django中render、render_to_response、HttpResponse、JsonResponse、Response的使用
  17. 图像表格实线和虚线检测
  18. 如何将pdf转化成word文档呢?
  19. 数据库例题(创建数据库SPJ包含S、P、J和SPJ表)
  20. bootstrap3 文件上传插件fileinput中文说明文档

热门文章

  1. 深入AMCL(四):相机如何辅助AMCL自动全局定位
  2. PGA内存空间的分配与回收
  3. 程序员笔记逆波兰表达式计算
  4. 智能手表短信读取实现具体教程(带有eSIM卡,无短信功能,可安装手表QQ的智能手表)Version2.0改进版
  5. 【号外】支付宝小程序,惊呆我的小伙伴
  6. OpenMV入门(下)
  7. 阿里面试分享,4面技术5面HR附加笔试面,庆幸已经拿到offer了~
  8. AlexNet模型思想详解及核心代码实现
  9. ACCP6.0 教程课件,可用
  10. 基于SSM的网上商城(中)