尽量用pass-by-reference-to-const(const引用)替换pass-by-value(传值)

来源:互联网 发布:淘宝客服有前景吗 编辑:程序博客网 时间:2024/04/30 07:16

        默认情况下C++以pass-by-value传递对象至函数(或从函数返回)。

    eg1:

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); // 函数以 by value 方式接受参数Student plato;bool platoIsOk = validateStudent(plato); // 调用函数
        Student的copy构造函数会被调用,以plato为蓝本将s初始化。而当validtaeStudent返回时s会被销毁。详细深究的话,应该是以by value方式传递一个Student对象会导致调用一次Student copy构造函数,一次Person copy构造函数,4次String copy构造函数;相应销毁时总共需要调用6次析构函数。所以总成本是“六次构造函数和六次析构函数”!

        使用pass by reference to const进行回避:

bool validateStudent(const Student& s);
        这种传递方式效率就高很多,没有任何构造函数或析构函数被调用,因为没有对象被创建。这里的const使用是重要的,不这样做的话调用者会忧虑validateStudent会不会改变他们传入的哪个Student。


        以by reference方式传递参数还可以避免slicing(对象切割)问题

        如果函数参数是基类对象,当传入一个派生类对象时,会造成派生类对象相比基类对象“之所以是个派生类对象”的所有特性化信息都会被切除。解决切割(slicing)问题的办法,就是以by reference to const的方式传递参数。

        闲谈:有一次面试的时候问到了我这个问题,没有很好的回答上来“多态发生为什么需要传指针而不直接传递对象,传递对象有什么后果?”,现在可以很好的总结出答案。


        由C++编译器的角度来看,references往往以指针实现出来,一次pass by reference 通常意味真正传递的是指针。如果对象属于内置类型(例如int),pass by value往往比pass by reference的效率高些(原因请看:C++ 传参时传内置类型时用传值(pass by value)方式效率较高)。

    1、内置类型都相当小,因此有人觉得,小型types都是pass-by-value的合格候选人,这个理论不可靠,对象小并不意味着其copy构造函数并不昂贵。许多对象(包括大多数STL容器)内容的东西只比一个指针多一些,但复制这种对象却需承担“复制那些指针所指的每一样东西”,那将非常昂贵。

    2、即使小型对象拥有并不昂贵的copy构造函数,但效率优化上可能有争议。某些编译器会针对“内置类型”进行优化,比如某些编译器拒绝把只由一个double组成的对象放进缓存器,但是很乐意在一个正规基础上对光秃秃的doubles那么做。这种情况下,更应该以by reference方式传递此等对象。

    3、作为一个用户自定义类型,其大小容易有所变化。一个type目前虽然小,将来也许会变大,因为其内部实现可能改变。


结论:
        1、尽量以pass-by-reference-to-const替换pass-by-value,前者通常毕竟高校,并可避免切割问题(slicing problem)。

        2、以上规则并不适用于内置规则,以及STL的迭代器和函数对象。对它们而言,pass-by-value往往比较适当。

0 0
原创粉丝点击