重温《C++ Primer》笔记九 const形参小结

首先,形参大致可以分为三种:非引用形参、引用形参和指针类型形参。


一、非引用形参

在传递参数的时候,不论是所谓的传值还是传址,实际上都是实参值到形参值的复制,其中的区别只是复制的是普通对象还是引用对象而已。对于非引用形参,通过参数传递之后,形参是实参的一个副本,而非引用形参使得复制后形参与实参并没有任何关联,因此,在函数中对形参的任何操作将不会影响到实参的值,因此,不论实参是变量还是常量,形参的操作是基于副本的,将不受任何的限制。如下例子:

void func1(int num)
{
	int value1 = num;
}

void func2(const int num)  //const形参
{
	int value1 = num;
}
void main()
{
	int num1 = 1;
	const int num2 = 2;
	func1(num1);
	func1(num2);  //ok,将const对象传递给非const形参
	func2(num1);
	func2(num2); 

这里,尽管实参是const常量,仍然可以传递给非const形参,因为形参操作的是实参的副本,并不直接访问const实参,因此,不论实参是不是const常量都与形参无关了。

对于编译器,尽管func2的形参是const,但是编译器将func2的定义视为其形参被声明为普通的int一样。


二、对于引用形参

首先需要知道的是:引用是一个特殊指针常量,编译器自动对其进行间接访问。因此,对于引用的操作便只有一种:对此特殊指针常量的间接访问。因此,尽管引用形参仅仅只是实参地址的副本,但是引用的操作只是间接访问,从而导致必须影响到与引用关联的内存区域(实参对象)了。另外一点,我们常说的const引用指的是指向const对象的引用。所以,如果实参为const对象,则必须要求形参为const类型。
<span style="font-size:14px;">void func1(int &num)
{
	int value1 = num;
}

void func2(const int &num)  //const引用形参
{
	int value1 = num;
}
void main()
{
	int num1 = 1;
	const int num2 = 2;
	func1(num2);  //error,不能将const对象传递给非const形参</span>
上面的func1函数的形参是const,这使得在func1函数中能够自由访问形参的值,如果传递的实参为const,则会错误访问const对象。错误提示如下:


三、对于指针形参

引用是指针的一个特例。指针的操作有两种:1、直接访问,这只会改变地址值;2、间接访问,会改变与地址关联的内存区域。在传递参数的时候,形参将得到一个实参的复制,即地址形参将得到一个地址实参的副本。如果是在地址值的级别上访问,则不会影响到实参的内容。因此,在形参地址的级别上加上const将不会有任何的作用,这与非引用形参一样。如果是在地址关联的对象的级别上访问,则会影响到实参的内容,因此,如果在地址关联的对象上加上const(即声明为指向const对象的指针),则与引用类似了。
对于指针形参,能够影响到实参的只有与指针关联的内存区域,因此,只有在指针形参所指向的对象是否为const才会影响到实参。

总结:对于编译器而言,并没有真正的const形参,const非引用形参与普通形参将被编译成同一个函数,即普通形参函数。而对于指针常量形参,*const形参将于*形参被编译成同一个函数,即*形参函数。只有在引用与指针形参中与引用与指针关联的对象上加上const才与不加const形参不同。(这在函数重载的时候非常有用,前两种算作函数重定义,而第三种才算是函数重载)


发布了68 篇原创文章 · 获赞 42 · 访问量 22万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章