effective c++条款20:宁以pass-by-reference-to-const替换pass-by-value

版权声明:转载请注明出处,谢谢!!! https://blog.csdn.net/qhdhnbd110/article/details/83574692

1. 更高效

考虑如下的一个base class和derived class:

class Base
{
private:
    std::string name;
    std::string address;
public:
    Base(){}
    ~Base(){}

};
class Derived:public Base
{
public:
    Derived(){}
    ~Derived(){}
};

如果存在一个函数需要以一个Derived对象为参数,而你以pass-by-value方式传递:

void Fun(Derived w);
Derived h;
Fun(h);

我们都知道,以pass-by-value方式传递参数就是构造一个原参数的一个副本,那么Fun函数构造一个derived对象的成本为:

Derived的构造+Base的构造+name的构造+address的构造;

在函数结束后,还需要Derivede的析构+Base的析构+name的析构+address的析构;

而对pass-by-reference-to-const需要的成本:

一个指针(传引用的底层实现往往是指针)。

很明显,pass-by-reference-to-const比pass-by-value更高效。

2. 避免对象切割

#include<iostream>
using namespace std;
class Base
{
public:
    Base(){}
    ~Base(){}
public:
    virtual void Show() const 
    {
        cout << "Base" << endl;
    }
};
class Derived:public Base
{
public:
    Derived(){}
    ~Derived(){}
public:
    void Show() const
    {
        cout << "Derived" << endl;
    }
};
void Fun(Base w)
{
    w.Show();
}
void Fun1(const Base &w)
{
	w.Show();
}
int main()
{
    Derived Ob;
    Fun(Ob);
    Fun1(Ob);
    return 0;
}

运行结果:

可以发现,如果以pass-by-value方式传递参数,那么Fun函数会以Base Class的构造函数创建一个对象副本,而以pass-by-reference-to-const方式传递参数,Fun1函数会保持原有的类型。

3. 内置类型、STL的迭代器和函数对象并不一定适合pass-by-reference-to-const方式

因为pass-by-reference-to-const往往以指针方式实现,所以如果你要传递的参数为一个内置类型,那么pass-by-value方式往往是一个更高效的选择。

对于STL迭代器和函数对象,习惯上他们都被设计为pass-by-value方式,所以pass-by-value方式往往是一个更高效的选择。

对于许多STL容器,虽然大小只比一个指针大一点点,但是复制STL容器就意味着复制内部指针所指向的所有东西,代价非常昂贵。

对于很小自定义对象,他们以后可能被修改,变得越来越大,所以以“对象体积大小来衡量以哪种方式传递”是一个不可靠的推论。

结论:

尽量以pass-by-reference-to-const方式替换pass-by-value方式,前者往往更高效并且可以避免切割问题。

以上结论并不适用于函数对象,STL迭代器以及内置类型,他们往往以pass-by-value方式更高效。

猜你喜欢

转载自blog.csdn.net/qhdhnbd110/article/details/83574692
今日推荐