我们先来看一个简单的程序:

 

#include <iostream>
using namespace std;

class A
{
private:
	string name;
	string addr;
};

void fun(A a)
{

}

int main()
{
	A a;
	fun(a);

	return 0;
}

      我们在调用fun函数的时候, 会有形参的拷贝, 会调用A的构造函数, 由于name和addr都是string对象, 所以也会有构造。 也就是有三次构造, 对应的有三次析构, 消耗巨大, 何不以引用来传递呢?

 

 

#include <iostream>
using namespace std;

class A
{
private:
	string name;
	string addr;
};

void fun(A &a) // 引用, 不涉及临时对象的拷贝
{

}

int main()
{
	A a;
	fun(a);

	return 0;
}

      这样, 就省略了3次构造, 3次析构, 效率杠杠的。 但是, 上述程序还有个问题, 我们可能担心fun函数改变了a, 所以, 应该加上const, 形成const形式的引用, 如下:

 

 

#include <iostream>
using namespace std;

class A
{
private:
	string name;
	string addr;
};

void fun(const A &a) // const形式的引用, 从此再也不用担心fun函数改变a了
{

}

int main()
{
	A a;
	fun(a);

	return 0;
}

 

 


      而且, 熟悉C++多态的朋友肯定知道, 拷贝会导致对象切割, 如下:

 

#include <iostream>
using namespace std;

class A
{
public:
	virtual void test()
	{
		cout << "A" << endl;
	}
};

class B : public A
{
public:
	virtual void test()
	{
		cout << "B" << endl;	
	}
};

void fun(A a) // 对象切割
{
	a.test();
}

int main()
{
	B b;
	fun(b);

	return 0;
}

      结果为:A

 

    

      为了避免对象切割, 我们用引用, 为了避免改变b, 我们加const, 于是乎:

 

#include <iostream>
using namespace std;

class A
{
public:
	virtual void test()
	{
		cout << "A" << endl;
	}
};

class B : public A
{
public:
	virtual void test()
	{
		cout << "B" << endl;	
	}
};

void fun(const A &a)
{
	a.test(); // error
}

int main()
{
	B b;
	fun(b);

	return 0;
}

      但是, 但是, 但是, 编译不通过, 为什么呢? 因为fun中, a是const引用, 所以不能调用非const函数,  修改为:

 

 

#include <iostream>
using namespace std;

class A
{
public:
	virtual void test() const  // const函数
	{
		cout << "A" << endl;
	}
};

class B : public A
{
public:
	virtual void test() const // const函数
	{
		cout << "B" << endl;	
	}
};

void fun(const A &a)
{
	a.test();
}

int main()
{
	B b;
	fun(b);

	return 0;
}

      这样就OK啦, 结果为:B .可见, 对象没有被切割。

 

 

      最后, 让我们来和Scott Meyers一起来嚷嚷:宁以pass by reference to const替换pass by value.

 

 




 


本文转载:CSDN博客