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

Effective C++ 条款20:尽量用传引用替换传值

2017-09-20 10:39 676 查看

避免浪费时间空间

默认情况下,C++的函数调用是传值调用,也就是说形参拷贝实参的内容。考虑以下继承体系:

class Person
{
private:
string name;
string address;
public:
Person(){}
virtual ~Person(){}
};

class Student: public Person
{
private:
string schoolName;
string schoolAddress;
public:
Student(){}
~Student(){}
};


假设有个函数接口:

void PrintStudent(Student ss);


那么如果这样调用:

Student s;
PrintStudent(s);


形参ss就会把实参s完完整整地复制一遍,这其中先后调用了Person的构造函数和Student的构造函数,而每个类中又包含两个string对象,所以总共会调用6次构造函数(4个string构造、Person构造和Student构造,注意这里的构造包括构造函数和拷贝构造函数),相应也会调用6次析构函数(注意当有派生关系存在时,基类的析构函数应该声明成虚的,这个在条款七中提到过)。

实际上,在PrintStudent里面其实只是打印Student的信息,并没有对这个对象做出修改,所以完整的拷贝显然既浪费时间,又浪费空间。如果你习惯使用C,那么会想到把形参作成指针,这样拷贝只是拷贝一个指针的内容而已,像下面这样:

void PrintStudent(Student* ss);//声明
PrintStudent(&s);              //调用


或者也可以使用引用:

void PrintStudent(Student& ss);//声明
PrintStudent(s);               //调用


就可以了,引用在原来代码的基础上只是多加了一个&,看上去比指针更自然,这算是C++的一个优点吧,在函数体中也可以避免对指针的操作,从而减少出错的可能性。

避免对象切割问题

以by reference方式传递参数也可以避免slicing(对象切割)问题。当一个派生类对象以by value方式传递并被视为一个base class对象,base class的copy构造函数会被调用,而“造成此对象的行为像个派生类对象”的那些特化性质全被切割掉了,仅仅留下一个base class对象。



总结

尽量以pass-by-reference-to-const来代替pass-by-value,前者通常比较高效,并可以避免切割

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