您的位置:首页 > 编程语言 > C语言/C++

《Effect C++》学习------条款20 :宁以pass-by-reference-to-const替换pass-by-value

2016-09-19 21:40 302 查看
缺省的情况下,C++是以by value方式传递对象至函数。函数实参都是以实际实参的复件为初始值,而调用端获得的亦是函数返回值的一个复件。这些复件系由对象的copy构造函数产出,这可能使得pass by value成为昂贵的操作。考虑下面的继承体系:

classPerson{

public:

Person();

vitual~Person();

private:

std::stringname;

std::stringaddress;

};

classStudent:publicPerson{

public:

Student();

virtual~Student();

private:

std::stringschoolName;

std::stringschoolAddress;

};


现在有一个调用函数validateStudent,要调用一个Student实参并返回它是否有效?

bool validateStudent(Student s);   //函数以by value的方式接受学生
Student plato;   //柏拉图,苏格拉底的学生
bool platoIsOK = validateStudent(plato);   //调用函数


上面的例子中先后调用了Person的构造函数和Student的构造函数,而每个类中又包含两个string对象,所以总共会调用6次构造函数(4个string构造、Person构造和Student构造,注意这里的构造包括构造函数和拷贝构造函数),相应也会调用6次析构函数(注意当有派生关系存在时,基类的析构函数应该声明成虚的,这个在条款七中提到过)。

面对这种情况,使用pass-by-reference-to-const,传引用调用可以减少构造函数的调用外,还可以防止对象切割。Person&只是告诉编译器它保存的地址对应的内容是一个Person类型的,它会优先把这个内容往Person上去套,但如果里面有虚函数,即使用了virtual关键字,那么编译的时候就会往类中安插一个虚指针,这个虚指针的指向将在运行时决定,这就是多态的机制了,它会调用实际传入的那个对象的虚函数,而不是基类对象的虚函数。

如果没有接触过多态,上面说的可能就会有难度,其实也可以简单的理解成,如果不加引用或指针,那么形参就会复制实参,但形参是基类的,它没有实参多出来的那部分,所以它就不能复制了,只能丢弃了;但如果加了引用或指针,那么无论是什么类型的,都是保存实参的地址,地址是个好东西啊,它不会发生切割,不会丢弃。

请记住:

[x] 尽量以pass by reference to const替换pass by value。前者通常比较高效,并可避免切割的问题。

[x] 以上规则并不适用于内置类型,以及STL的迭代器和函数对象。对它们而言,pass by value更加适当。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐