传参时,使用引用替换变量

第一个原因。。。

C++默认使用变量的方式传递对象。假如没有另外指定,函数的参数都是以实参的副本为初值,而函数的返回值也是一个复件。这些复件由对象的copy构造函数产出,这会让值传递成为昂贵的操作。来一个简单的例子

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;
};
bool validateStudent(Student s);          //以值的方式接受学生
Student plato;                            //柏拉图
bool platoIsOK = validateStudent(plato);  //调用函数  

简单地看,Student的复制构造函数在传入参数的时候会被调用,产生plato的副本初始化s,同样,返回的时候将s销毁,调用一次析构函数。也就是参数的传递成本是“一次Student的复制构造函数与一次student的析构函数”。但是,让我们解剖一下Student。

一个Student中有4个string对象,2个继承自Person,2个Student自己定义。而每个string也是一个实例,意味着每个Student初始化的时候string会被初始化时,就会初始化4个string,一个Person,每个Student销毁时,就会销毁四个string,一个Person,所以,真正的调用这个函数的时候,参数传递的成本是“六次构造函数与六次析构函数”!!!

想到这些,顿时间十分堪忧我们程序的性能。解决的方法就是,使用引用代替普通的值传递。当然,假如需要保护形参,我们还可以加上const限制。

bool validateStudent(const Student& s);

因为引用实际上是通过指针来实现的。引用一句话,"变量可以看成变量的别名”,也就是,使用引用是不会创建新的实例的。所以使用这种传递方式,效率高了很多,没有任何构造函数与析构函数被调用,因为没有创建任何新的实例。

第二个原因。。。
当然,使用引用的好处不仅仅是这些。使用引用的方式传递参数,还可以避免对象切割的问题。当派生类的对象传递给基类的对象时,调用的是基类的构造函数,派生类的那些特性将会被全部切割掉。试想一下有如下代码。

class Window
{
pubic:
    virtual void Display()const;    //显示窗口的名字  
};
class WindowWithScrollBars:public Window
{
public:
    virtual void Display()const;    //显示窗口和内容
};

当我们用一个WindowWithScrollBars类型的对象初始化一个Window类型的对象后,在Window对象后调用Display,一切不值得惊讶又让人懊恼,我想显示一个窗口和内容但实际上它只给了我一个窗口的名字。学习了虚函数之后,我们知道这可以通过指针来解决,同样的,使用引用也能解决这个问题。

第三个原因。。。

编译器对内置类型与用户自定义类型的态度不太一致。比如,有些编译器会将一个double放入缓冲器中,但是却拒绝将一个只有double的class放入缓冲器中。而当我们使用引用的时候,引用是指针实现的,编译器当然会将指针放入缓冲器中。

第四个原因。。。

你认为你的class很小,直接使用变量传递与使用引用传递没有区别。但是,没有人能够保证class一直很小。就比如,class里面只有一个string,看起来真的很小,但不同的库的string大小相差非常大,当你认为class很小的时候,它实际已经无限膨胀了。再比如,假如没有使用引用,每次向class中增加内容的时候,你得小心翼翼增加的内容是否对你的性能会造成很大的影响。而假如你不希望有这种心理阴影,还是使用引用吧。

但是话说回来,又不是要求我们每时每刻都要使用引用来代替变量,比如,当我们使用STL库的时候。STL库习惯被设计成以变量的方式传递。比如传递其迭代器。所以,当我们使用STL库的时候,我们直接使用变量传递参数会优于引用。

总结一下

  1. 使用引用传递参数会比变量更高效
  2. 使用引用传递参数可以避免对象切割的问题
  3. 不是所有的时候都使用引用比时候变量好,比如当使用STL库或者函数对象的时候。

原文链接: https://www.cnblogs.com/suimeng/p/4885491.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    传参时,使用引用替换变量

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/223178

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月13日 上午11:59
下一篇 2023年2月13日 上午11:59

相关推荐