前情提要
缺省情况下C++以pass-by-value
方式传递至函数。除非另外指定否则函数的参数都是以实参的副本为初值。并且调用端所获得的对象也是函数返回值的一个副本。这些副本是由对象的copy构造函数
产生的。这就可能使得pass-by-value
成为性能开销的操作。
class Person{
public:
Person();
virtual ~Person();
...
private:
std::string name;
std::string address;
};
class Student: public Person{
public:
Student();
~Student();
...
private:
std::string schoolName;
std::string schoolAddress;
};
pass-by-value
现在有如下的代码段
bool validateStudent(Student s); // 函数以pass-by-value方式接受学生对象
...
Student plato;
bool platoIsOK = validateStudent(plato);
- 这里的函数会发生如下几件事
Student
的copy构造函数
被调用,以plato
为副本将形参s
初始化。- 函数结束返回的时候,
Student
的析构函数
被调用,将形参s
析构。- 总的函数调用开销有
- 一次
Student
的copy构造函数
和析构函数
- 一次
Person
的copy 构造函数
和析构函数
- 四次
string
的copy构造函数
和析构函数
一共会有6次copy构造函数
和析构函数
,那么有没有什么方法可以避免这些构造和析构函数呢。事实上C++中是有的,而且非常优雅。就是pass-by-reference-to-const
!!
pass-by-reference-to-const
bool validateStudent(const Student &s);
- 这种函数参数调用的方式要比
pass-by-value
要高效的多,因为它避免了刚刚所有的构造函数和析构函数开销。值得注意的是这里const Student &s
中的const
。
- 在最原先的
pass-by-value
版本中的validateStudent
函数中,我们可以确保函数内部不会修改调用者的实参,因为函数只能修改实参的一个副本而已。- 而在现在这一个
pass-by-reference-to-const
版本中我们就必须需要一个const
关键字去限制validateStudent
函数内部对实参进行修改。