//--------------------------------------------------------------------------- #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,这也间接提示编辑者,该调用方法是有问题的。