//---------------------------------------------------------------------------
#include <vcl.h> //CB6.0
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------
class Complex
{
public:
Complex(double r=0.0, double i=0.0) { real = r; imag = i; }
void display() const { cout<<real<<'+'<<imag<<'i'; }
Complex add(const Complex& x)const ;
void complex_add(const Complex& x, const Complex& y) ; //非友元,为什么可行?
//friend
Complex complex_add2(const Complex& x, const Complex& y);
private:
double real;
double imag;
};
//---------------------------------------------------------------------------
//如何实现两个复数相加?
Complex Complex::add(const Complex& x) const
{
Complex temp;
temp.real = this->real + x.real;
temp.imag = this->imag + x.imag;
return temp;
}
//---------------------------------------------------------------------------
void Complex::complex_add(const Complex& x, const Complex& y) //非友元函数
{
this->real = x.real + y.real;
this->imag = x.imag + y.imag;
}
//---------------------------------------------------------------------------
Complex Complex::complex_add2(const Complex& x, const Complex& y) //一定要是友元函数?为什么?
{
Complex temp;
temp.real = x.real + y.real; //非友元情况下temp不能访问real,为什么?
temp.imag = x.imag + y.imag;
return temp;
}
//---------------------------------------------------------------------------
//测试代码:
int main(int argc, char* argv[])
{
Complex a(1.0, 2.0), b(3.0, 5.0), c;
//c = a.add(b); // OK
//c.complex_add(a,b); // OK
c = complex_add2(a,b); // ?why not?
c.display();
return 0;
}
如类的声明中描述的那样,假设 complex_add2 函数不被声明为类Complex的友元,那么在测试代码中,
c = complex_add2(a,b); // ?why not?
这一行就不能通过编译,这是为什么呢?它不是已经被声明为成员函数了吗?
原来,上面这种函数调用方法,正是友元的常见调用形式!
如果你需要将 complex_add2 作为 Complex的成员函数来调用,那么正确的调用方式应该是:
"某Complex对象.complex_add2(a,b);"
只要这个对象是有效的,那么其返回值就可以正确赋值给c。
比如:c=a.complex_add2(a,b);
又比如:c=c.complex_add2(a,b);
而不必关心是谁(Which available object)调用了该成员函数。
成员函数的调用方式与友元之不同正体现于此,这也在测试代码 add 以及 complex_add 函数的调用方法中得以展现。
*************************
此外,如果被声明为成员函数,那么在函数定义时,函数名前加作用域“Complex::”是不可避免的。
如果直接使用 c=complex_add2(a,b); 那么编译器会提示调用了一个未被定义的函数complex_add2,这也间接提示编辑者,该调用方法是有问题的。