缺省情况下,C++以by value 方式传递对象至(或来自)函数。
除非你另外指定,否则函数参数都是以实际实参的副本为初值,而调用段所获得的亦是函数返回值的一个副本。这些副本都是由对象的copy构造函数产出的,这可能使得pass-by-value 称为昂贵的(费时的)操作。

考虑下述例子:

  1. class Person {
  2. public:
  3. Person();
  4. virtual ~Person();
  5. ...
  6. private:
  7. string name;
  8. string address;
  9. };
  10. class Student: public Person {
  11. public:
  12. Student();
  13. ~Student();
  14. ...
  15. private:
  16. string schoolName;
  17. string schoolAddress;
  18. };
  19. bool validateStudent(Student s);
  20. Student plato;
  21. //传递参数方式一
  22. bool platoIsOK = validateStudent(plato);
  23. //传递参数方式二
  24. bool validateStudent(const Student& s);

以方式一传递参数时,由于C++默认的是by value 的方式,因此,会构造一个Student对象,并且以plato进行初始化。这会导致调用Student的构造函数,而当函数返回时,势必又要调用其析构函数。 这只是表面,由于Student继承自Person,因此在创建Student时,势必要调用其基类的构造函数来初始化其基类部分,销毁时也是同样的。而又由于Person 和Student类中又内涵string对象,因此在构建时,又要调用string对象的构造和析构函数。全部算在一起,一共会调用6次析构函数和6次构造函数。这是非常耗时的操作。

而避免上述耗时的方法也非常简单,即以pass-by-value-to-const方式传递参数即可。这样的传递方式不会有任何新的对象被创建,因此也不会调用析构函数和构造函数。

一个函数的形参,接收的是一个基类的对象。 但如果调用这个函数时,传递的是一个派生类对象的话,那么形参只会构造这个派生类对象的基类部分作为实参。因此,当在函数内使用这个派生类对象时,它的所有被特化的部分都会表现的是基类的特性。

举栗子:

  1. class Window {
  2. public:
  3. ...
  4. 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. cout << w.name();
  15. w.display();
  16. }
  17. //解决办法
  18. void printNameAndDisplay(const Window& w)
  19. {
  20. cout << w.name();
  21. w.display();
  22. }

参数以pass-by-reference-to-const 方式传递。

pass-by-reference-to-const 的底层实现是指针,pass-by-reference-to-const方式通常意味着传递的是指针。因此,如果是内置类型的参数,pass-by-value比pass-by-reference-to-const的效率更高一些。同样的,对于STL的迭代器,以及函数对象,pass-by-value比pass-by-reference-to-const的效率更高一些。

因此对于内置类型、STL迭代器、函数对象 这三类,使用by value方式传递参数更好。

不是的,从下述三个方面考虑。

版权声明:本文为lasnitch原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/lasnitch/p/12764176.html