首页 > 其他分享 >Item20:用传const引用取代传值

Item20:用传const引用取代传值

时间:2024-04-02 11:24:18浏览次数:27  
标签:std const string Person Item20 Student 用传 public

芝士wa
2024.4.2
Item20链接


“缺省情况下,C++以传值的方式将对象传入或传出函数,这种传递方式会带来昂贵的代价。”

举例分析:

  class Person {
  public:
    Person();                          // parameters omitted for simplicity
    virtual ~Person();                 // see Item 7 for why this is virtual
    ...

  private:
    std::string name;
    std::string address;
  };

  class Student: public Person {
  public:
    Student();                         // parameters again omitted
    virtual ~Student();
    ...

  private:
    std::string schoolName;
    std::string schoolAddress;
  };

考虑以下代码,

bool validateStudent(Student s);           // function taking a Student
                                           // by value
Student plato;                             // Plato studied under Socrates

bool platoIsOK = validateStudent(plato);   // call the function

首先创建了一个学生对象,然后通过传值的方式调用函数,在这次函数调用时,发生了什么呢?形参的拷贝!
一个Student对象内部包含了两个string,当我们创建student的时候,也构造了两个string,同时,因为student继承了Person,一个person对象也被构造出来,而Person内部又包含另外两个string对象。
最终,以传值方式传递一个Student对象的后果就是导致:

  • 一次Student拷贝构造函数的调用
  • 一次Person拷贝构造函数调用
  • 四次string拷贝构造函数调用
  • 六次析构函数调用

采用传引用的方式可以避免这些拷贝,

bool validateStudent(const Student&s);

"以传引用方式传递形参还可以避免slicing problem(切断问题)。"

考虑下面的代码:

  class Window {
  public:
    ...
    std::string name() const;           // return name of window
    virtual void display() const;       // draw window and contents
  };

  class WindowWithScrollBars: public Window {
  public:
    ...
    virtual void display() const;
  };

下面的函数原意是实现打印并显示的功能,

  void printNameAndDisplay(Window w)
  {
    std::cout<<ww.name();
    w.display();
  }

  //调用
  WindowWithScrollBars wwsb;
  printNameAndDisplay(wwsb);

形参wwsb通过值传递给函数,实际上这里的wwsb会被当成window类的对象,display调用总是调用Window::display,而不是WindowWithScrollBars::display,多态无法实现。

绕过slicing problem(切断问题)的方法就是以传const引用方式传递wwsb。

  void printNameAndDisplay(const Window& w);

现在w将表现出WindowWithScrollBars的特性。


“如果你有一个内建类型的对象,例如int,以传值方式传递它常常比传引用的方式更高效”

通常情况下,对于内建类型,STL iterator(STL迭代器)和函数对象类型,采用值传递的方式会更高效,对于其他类型,用传const引用代替传值。

标签:std,const,string,Person,Item20,Student,用传,public
From: https://www.cnblogs.com/cheese-wa/p/18110186

相关文章

  • 【异常】Spring的依赖注入(DI)系统提示异常,因为漏了一个实现类导致了错误Parameter 0 of
    一、异常内容2024-04-0111:44:39.912[main]ERRORorg.springframework.boot.diagnostics.LoggingFailureAnalysisReporter-***************************APPLICATIONFAILEDTOSTART***************************Description:Parameter0ofconstructorinc......
  • C++ 引用传递 超级详细 小白也行
    一.引用的概念引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。(本名和小名共用一块地址)例如:就像是给你取小名,本名小名都是你,所有作用也都一样。 类型&引用变量名(对象名)=引用实体(如图下)......
  • constexpr有什么用处?
    constexpr有什么用处2024/3/3021:07:25constexpr是C++11引入的关键字,用于声明一个常量表达式(constexprexpression)。常量表达式是在编译时就能够计算出结果的表达式。使用constexpr关键字可以告诉编译器,某个函数或变量的值可以在编译时确定,并且可以被用于编译时计算。这......
  • const7虚拟机jupyternotebook打开页面是空白
    jupyterNoteBook网页空白各种解决方法(实在不行用pyCharm替代Chrome)_为什么jupyternotebook打开是空白页面-CSDN博客找了好久解决方案,安装好之后是可以打开home页面的但是没有任何显示,只有空白,改了很多配置文件但都是以失败告终,终于在这个博主这里解决了,采取的方法就是卸载jup......
  • 指针和const修饰符
    详解指针(1)什么是指针指针类型指针运算1指针在生活之中,我们每个人的家中都有门牌号,而正因为有了门牌号我们才能够正确而快速的找到自己的家,这个门牌号就相当于我们的地址。而在C语言之中也有这么一种东西----地址,我们可以通过地址找到存储在该内存单元的数......
  • UE4 C++ Widget的NativeConstruct 与 NativePreConstruct
    构造函数由于Widget是由UE的反射系统创建的,其生命周期由UE引擎管理,所以并不存在构造函数,UE为Widget类定义了两个虚函数NativeConstruct与NativePreConstruct来充当构造函数的作用。而这两个函数的调用都必须在Widget被实例化之后才能进行调用如何在Widget中获取角色在蓝图节......
  • Item2:用consts,enums和inlines取代#defines
    芝士wa2024.3.29Item2链接“用compiler(编译器)取代preprocessor(预处理器)”,问题就在于因为#define不被视为语言的一部分要理解这句话,需要先了解C++程序的编译过程:1.预处理preprocess预处理是编译前的准备工作。在这一步中,预处理器会执行以下操作:替换所有的宏定义(#defin......
  • java中的什么是值传递,什么是引用传递
    值传递(PassbyValue):值传递意味着在方法调用时,实际参数的值被传递给方法中的形式参数,即在方法内部修改形参的值不会影响实参的值。Java中的基本数据类型(如int、float、double等)就是值传递的典型例子。publicclassMain{publicstaticvoidmain(String[]args){......
  • D. XOR Construction
    题解首先根据b1⊕b2=a1,b2⊕b3=a2...bj⊕bj+1=aj我们不难得出b1​⊕bj+1=a1⊕a2⊕a3....⊕aj因此我们只需要确定b1的值就能够确定其余所有bi的值,而题目又要求我们的b处于0~n-1范围内,这实际上实在寻找一个 b1​ 使得异或出来的所有值越小越好,所以我们拆位,假设所有数字的第 i ......
  • 定义和调用传统方法
    publicclassDao{//--------自定义传统方法1------//返回值类型,方法名,形参publicstaticvoidprintBook(Stringname){if(name.equals("孔子")){System.out.println("孔子的代表作《论语》");return;}else......