条款20:宁以pass-by-reference-to-const替换pass-by-value
缺省情况下C++是以by value 传递的。其副本是对象本身的copy 构造函数自动调用的。
class Persion
{
private:std::string m_name;std::string m_addr;
};class Student : public Persion
{
private:std::string m_schoolName;std::string m_schoolAddr;
};bool IsValidStudent(Student s) {return true;}
调用
 Student s1;bool b_s = IsValidStudent(s1);

IsValidStudent函数调用行为如下:编译器调用student拷贝构造函数拷贝实参到形参,然后形参使用完后再调用析构函数,但该类调用远不止这些,如student的父类也需要调用拷贝构造函数,而persion中有两个string成员也需要调用拷贝构造函数,还有student也有两个string成员需要调用拷贝构造函数,而且这些调用完后还需要调用析构函数。就因为一个pass-by-value操作,而需要花费这么多成本。
pass-by-reference-to-const

将上面的IsValidStudent函数修改如下
bool IsValidStudent(const Student &s) {return true;}

这样没有调用任何的构造函数和析构函数,形参实际是实参的副本,因此需要加上const保护实参免修改。

对象切割
        当一个derived class对象以pass-by-value的形式传递给一个base-class对象时,base-class会调用拷贝构造函数,且会把derived class的所有行为都切割掉,即编译器只当成base-class处理。如果用reference和指针,可以防止对象切割。
class Persion
{
public:Persion(const string &name, const string& addr) : m_name(name), m_addr(addr) {}virtual ~Persion() {} //作为基类,需要定义虚析构函数string GetName() const {return m_name;}string GetAddr() const {return m_addr;}virtual void DisPlay() {cout<<"Person\n";}
private:std::string m_name;std::string m_addr;
};class Student : public Persion
{
public:Student(const Persion &persion, const string &sName, const string &sAddr):Persion(persion.GetName(), persion.GetAddr()),m_schoolName(sName),m_schoolAddr(sAddr){}string GetName() const {return m_schoolName;}virtual void DisPlay() {cout<<"Student\n";}
private:std::string m_schoolName;std::string m_schoolAddr;
};void DisPlayPersion(Persion persion)
{std::cout<<persion.GetName()<<endl;persion.DisPlay();
}

调用

  Persion p("cuancuan", "guangzhou");Student s1(p, "shiyan", "yuexiu");DisPlayPersion(s1);

输出

cuancuan
Person
结果很明显,没有调用student的Display函数
修改函数接口参数为pass-by-reference-to-const
void DisPlayPersion(const Persion &persion)

同样调用结果如下
cuancuan
Student
       看到结果,是不是有一种多态性的感觉,类似于将derived class地址赋给based clasa对象指针,调用虚函数DisPlay显示多态性。如果窥视c++编译器的底层,你会发现,references往往以指针实现出来,因此pass-by-reference通常意味着这真正传递的是指针。
      因此如果你有个对象属于内置类型(如int),pass by reference或pass by reference to const时,选择pass by value并非没有道理。这个忠告也适用于STL的迭代器和函数对象,因为习惯上它们都被设计为pass by value。迭代器和函数对象的实践者有责任看看他们是否高效且不受切割问题的影响。

记住

①尽量以pass-by-reference-to-const替换pass-by-value.前者通常比较高效,并可避免切割问题(slicingproblem).
②以上规则并不适合与内置类型,以及STL的迭代器和函数对象.对它们而言,pass-by-value往往比较适合.

条款20:宁以pass-by-reference-to-const替换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. 条款20 :宁以pass-by-reference-to-const 替换pass-by-value

    缺省的情况下,C++是以by value方式传递对象至函数.函数实参都是以实际实参的复件为初始值,而调用端获得的亦是函数返回值的一个复件.这些复件系由对象的copy构造函数产出,这可能使得pass b ...

  3. Effective c++学习笔记条款20:宁以 pass-by-reference-to-const替换pass-by-value

    Prefer pass-by-reference-to-const to pass-by-value         这个问题在在C++是非常常见的.传值和传引用巨大的差别在于你所使用的参数是其本身还 ...

  4. pass by value 与pass by reference 小结

    缺省条件下,c++都是以pass by value形式传递函数参数的,而值传递的参数,编译器知道这个参数收到保护,不会修改其值,实际上修改的都是通过拷贝构造函数另外创建的参数副本,当函数返回时还要调用 ...

  5. [C++学习] effective c++ 笔记 pass by value ,pass by reference

    在编写函数的返回值和形参的时候,能 传引用(pass by reference) 就不要 传值 (pass by value). 这样是为了少调用 copy constructor ,可以提高效率. ...

  6. Effective C++条款20:宁以pass-by-reference-to-const替换pass-by-value

    Effective C++条款20:宁以pass-by-reference-to-const替换pass-by-value(Prefer pass-by-reference-to-const to p ...

  7. 【Effection C++】读书笔记 条款20~条款23

    [Effective C++]Part4 设计与声明 条款20:宁以pass-by-reference-to-const替换pass-by-value 尽量以pass-by-reference-to- ...

  8. Java - 传参到底是哪种? pass by value or pass by reference

    在了解Java传参数是pass by value或是pass by reference之前,先了解=赋值的用法会对理解传参很有帮助 赋值(=)的用法 =的意义是赋值,但是这个赋值用在 基本类型 和 对 ...

  9. 数组名传参(pass by reference)

    数组名作为函数参数(pass by reference) 说明:以下定义了一个doube_array函数,接受整个数组为函数参数,将其中的值修改为原来的2倍. #include <stdio.h ...

最新文章

  1. java sax xml文件解析_java解析xml文件-DOM/SAX
  2. POJ2931不平等博弈
  3. 那些年,陪伴过我们的下载软件(上)
  4. c语言if大括号的作用,c语言if语句 用法是什么
  5. Delphi XE8 程序瘦身.编译后EXE最低90KB
  6. 软件测试面包屑什么意思,面包屑的用法面包屑有什么作用
  7. imfindcircles
  8. iPhone和iPad等苹果设备自主更新Beta系统
  9. Win10安装glove-python方法
  10. 00后南航大二学生自制火箭,成功发射后回收
  11. 大数据窥探:关于大数据的15条干货思考
  12. 大数据应用电子商务之精准推广
  13. Unix学习记录(二)
  14. 复旦大学计算机网络期末考试试题,复旦大学学习计算机科学技术学院期末试题练习题.doc...
  15. 【大数据审计】无须编程,批量提取图片并相似度比对,进行费用真实性审查
  16. 从10年全网第1,看海尔智家披荆斩棘换来的持续性
  17. 基于python的师生一体化学生信息管理系统——python期末设计!!!
  18. vissim交通仿真实验(2)--十字信号交叉口
  19. HTTPS到底是个啥玩意儿?
  20. 多目标优化算法:多目标原子轨道搜索算法MOAOS(提供Matlab代码)

热门文章

  1. 通用计算机s3,计算机中S1,S3,S4,S5各自的状态是什么?
  2. 搭建Gitea和Drone环境
  3. PPT批量替换字体、行间距操作
  4. google正在等待cnd.bootcss.com的响应
  5. [GXYCTF2019]BabySQli
  6. linux根分区写保护,目录写保护,求助大神
  7. MPU6050开发 -- 测试程序分析
  8. 自律是最大程度的自由
  9. 怎样通过百度文库引流?使得你的网络业绩倍增
  10. 新基建!腾讯宣布投入5000亿