这四种操作符居然不能当作友元重载

来源:互联网 发布:腾讯云wordpress建站 编辑:程序博客网 时间:2024/06/05 10:21

赋值操作符(=),下标操作符([]),函数调用操作符(()),指针成员访问箭头(->)必须重载为类成员函数。

Code:
  1. Code:   
  2. friend F operator=(const F& f1,const F&f2);//error C2801: “operator =”必须是非静态成员     
Code:
  1. F operator=(const F& f){   
  2.     this->n = f.n;   
  3.     this->d = f.d;   
  4.     return *this;   
  5.     //return F(f.n,f.d);   
  6. }  

这样做就对了,这是什么原因呢?

在C++ primer14.4Assignments Operators这一节当中提到:

类赋值操作符接受类类型形参,通常,该形参是对类类型的const 引用,但也可以是类类型或对类类型的非 const 引
用。如果没有定义这个操作符,则编译器将合成它。类赋值操作符必须是类的成员,以便编译器可以知道是否需要合成一个。

真是这样的吗?让我们看看代码

Code:
  1. #include <iostream>      
  2. using namespace std;      
  3. class F{      
  4.     int n;      
  5.     int d;      
  6. public :      
  7.     F(int n=0, int d=1):n(n),d(d){}      
  8.     friend ostream& operator<<(ostream& os, const F& f){      
  9.         os << '[' <<  f.n << '/' << f.d <<']';  //存在ostream缓冲区   
  10.         return os;   
  11.     }   
  12.     /*F operator=(const F& f){  
  13.         this->n = f.n;  
  14.         this->d = f.d;  
  15.         return *this;  
  16.         //return F(f.n,f.d);  
  17.     }*/  
  18. };      
  19. int main()      
  20. {      
  21.     F f1(3,5),f2(11,7);   
  22.     cout << (f1 = f2);//这里将赋值重载函数去掉之后还是可以实现,这是因为合成的原因,编译器判断f1与f2类型相同,从而对其进行了合成   
  23.     return 0;   
  24. }     
  25.   
  26.   
  27.   

 

在第 13.2 节中讲到:

大多数操作符可以定义为成员函数或非成员函数。当操作符为成员函数时,它的第一个操作数隐式绑定到this 指针。有些操作符(包括赋值操作符)必须是定义自己的类的成员。因为赋值必须是成员,所以this 绑定到指向左操作数的指针。因此,赋值操作符接受单个形参,且该形参是同一类类型的对象。右操作数一般作为 const 引用传递。

我们从这里了解到,C++封装的太结实,不透气啊

代码剖析:http://www.52rd.com/blog/Detail_RD.Blog_imjacob_17085.html