您的位置:首页 > 编程语言 > C语言/C++

关于函数的参数为类的引用时编译错误的分析

2014-04-08 22:12 288 查看
关于函数的参数为类的引用的分析
下面这段程序是重载“+”,使之实现两个复数的相加,并且利用了转换构造函数,可以将实数转换成复数类,程序如下:
#include<iostream>

using namespace std;

class Complex

{

public:

Complex(){real = 0;imag = 0;}

Complex(double r){real = r;imag = 0;}

Complex(double r,double i){real = r;imag = i;}

friend Complex operator + (Complex &c1,Complex &c2); //改为(Complexc1,Complex
c2)程序正确
void display();

private:

double real;

double imag;

};
Complexoperator + (Complex &c1,Complex &c2) //改为(Complexc1,Complex
c2)程序正确
{

return Complex(c1.real + c2.real, c1.imag + c2.imag);

}
voidComplex::display()

{

cout << "(" << real << "," << imag<< "i)" << endl;

}
intmain()

{

Complex c1(3,4),c3;

c3 = c1 + 2.5;

c3.display();

return 0;

}
这是一个错误的程序,编译不能通过,错在“+”重载函数用了“类的引用调用”,如果不用“类的引用调用”,改用“实参传递形参”,程序正确。为什么这里不能用“类的引用调用”呢??
 
在利用转换构造函数来实现复数和整型值相加的时候,我也遇到了上面最开始的问题。上面的内容是我在网上查找资料时copy下来的。后来,我又自己翻阅了谭浩强编的C++,找到了比较清楚的解释。
书中在介绍引用时强调,可以用常量或表达式对引用进行初始化,但此时必须用const作声明。
为什么一定要用const作声明?这是我的最先有的一个疑问,想必你也是的。下面分析。
引用,一般地来讲是不能被初始化的。为什么

?因为引用是和被引用的变量共享存储单元的,编译系统是不会给它分配存储空间的。那么,引用只能被声明,不能被定义了。
如果你一定要给引用初始化,可以,但必须用const了。为什么?

编译器处理引用初始化并不是一步完成的。例如,上面代码把2.5传给引用,编译器首先时在内部生成了一个临时变量,然后通过临时变量再赋给引用。代码表示下:
double temp = 2.5;
Complex &c2 =temp;
这里就涉及到了我们问题的关键所在了。改变引用的c2值,同样会改变temp的值,但是,2.5的值却不能被修改。我们把引用作为形参,如果改变引用的值,是希望同时能够改变传递的实参的值的。这就与我们上面例子分析的结果产生了矛盾。与其允许修改引用的值而不能满足用户的需要,还不如不允许修改,这就是C++对这类引用必须要加const的原因。了解了我前面提到的2个为什么,相信你就能明白了。
4000

那么最初遇到的问题,根据上面的分析便很容易解决了。要么,我们不用引用,就用传值的方式,要么,我们在使用引用时,用const加以限定。如果你用了引用,又没加const,很不幸

,编译又会出现一些错误,而不能通过了。
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐