Item20:用传const引用取代传值

芝士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引用代替传值。

posted @ 2024-04-02 11:12  芝士wa  阅读(30)  评论(0)    收藏  举报