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

来源:互联网 发布:海康威视网络键盘 编辑:程序博客网 时间:2024/05/29 09:13

关于函数的参数为类的引用的分析

下面这段程序是重载,使之实现两个复数的相加,并且利用了转换构造函数,可以将实数转换成复数类,程序如下:

#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个为什么,相信你就能明白了。

那么最初遇到的问题,根据上面的分析便很容易解决了。要么,我们不用引用,就用传值的方式,要么,我们在使用引用时,用const加以限定。如果你用了引用,又没加const,很不幸敲打,编译又会出现一些错误,而不能通过了。

 

0 0
原创粉丝点击