【C++学习笔记】02-传递常量引用比传值更好

转载自:https://blog.csdn.net/Function_Dou/article/details/86608247

在c++中引入了引用, 而引用其实也就是指针, 只是使用起来更加的方便. 使用使用使得在函数传值时可以为对象创造一个别名, 操作时实际上就是操作原对象本身, 这样的传引用可以避免对象传递时产生临时对象. 这样避免就可以减少很多不必要的时间和空间的开销.

实际例子

以Effective C++条款20的例子来分析

class Person {
    string name, address;
public:
	Person();
    virtual ~Person();
    ...
};
class Student: public Person {
    string schoolName, schoolAddress;
public:
    Student();
    ~Student();
    ...
};

我们在函数值传递对象时, 究竟调用了多少次函数. 下面就来说明.

bool validateStudent(Student s);   

Student plato;
bool platoIsOK = validateStudent(plato);

上面函数创建临时对象时一共调用了6次构造函数, 6次析构函数. 原因 :

临时对象s会调用Person, Student两次构造和析构
类本身的成员对象有4个, STL容器的拷贝默认都是深拷贝, 所以4个string对象调用了4次构造函数, 4次析构函数
这还仅仅只是一个简单的对象的值传递, 如果对象的成员在复杂, 继承再多, 甚至函数调用的次数增加, 那么这些调用开销就很惊人了.

现在我们以常量引用再来分析:

bool validateStudent(const Student& s);

Student plato;
bool platoIsOK = validateStudent(plato);

现在函数参数并不会产生临时对象, 也就没有多余的时间和空间的开销, 这样就是对好的.

引用传递可以避免截断问题

使用传值改为传引用能避免对象被截断问题 : 主要影响就在于多态的表现.

同样以上面的为例 :

class Person {
    string name, address;
public:
	Person();
    virtual ~Person();
    virtual void position() { cout << "Person"; }
    ...
};
class Student: public Person {
    string schoolName, schoolAddress;
public:
    Student();
    ~Student();
    virtual void position() { cout << "Student"; }
    ...
};

采用传值的方式, 基类就会被截断, 失去多态性.

void position(Person s)
{
    s.position();	// Person
}

Person plato;
void platoIsOK = position(plato);

但是采用引用传递就能避免这样的问题.

void position(const Person s)
{
    s.position();	// Student
}

Student plato;
void platoIsOK = position(plato);

小结

并不是所有的函数传递都必须用引用, 如果传递的只是普通类型(int, char)最好就使用值传递, 这样开销比引用小, 但是如果传递的是对象, STL容器等最好就是传递引用, 常量引用更好.

你可能感兴趣的:(C++)