1 class A 2 { 3 protected: 4 int x; 5 public: 6 A(int a) { x = a; } 7 void show() 8 { 9 cout << "A is call "<<x << endl; 10 } 11 12 friend ostream &operator<<(ostream &os, const A& a) 13 { 14 //friend重载操作符跟普通的friend函数等价,可以使用私有成员,vs中该引用不能在类外定义,类外不能使用私有成员 15 os << a.x ; 16 return os; 17 } 18 19 //成员重载++前驱 20 A& operator ++() 21 { 22 ++x; 23 return *this; 24 } 25 26 //成员重载++后驱 27 //此处int为伪参数,不能写进一个传入变量,仅区分前后驱 28 A operator ++(int ) 29 { 30 //默认复制构造函数,不返回局部变量引用 31 A temp(*this); 32 ++x; 33 return temp; 34 35 } 36 37 //友元重载前驱++时,必须返回引用类型,后驱必须返回局部变量类型(不返回局部变量引用以免引起内存出错) 38 39 // friend A& operator ++(A&); 40 // friend A operator ++(A&, int); 41 42 }; 43 44 //A&operator++(A&a) 45 //{ 46 // a.x++; 47 // return a; 48 //} 49 // 50 //A operator ++(A& a,int) 51 //{ 52 // A p(a); 53 // a.x++; 54 // return p; 55 //} 56 57 //测试 58 int main() 59 { 60 61 A a(3); 62 cout << a++ << endl; 63 cout << ++a << endl; 64 }
总结:重载操作符号:重载操作符有两种方式,一种为成员重载 ,另外一种为友元 重载(部分编译器中友元重载无法引用私有对象,编译器错误,如vs2017输出重载的类外定义)
1.重载输入输出流时,如果采用std::ostream或者是std::istream作为默认版本,即系统默认版本,则返回类型和参数类型必须为其引用,且流参数不能为const,原因在于,
iostream这个标准流,没有复制构造函数,其复制形式在c++11源码中,有如下声明
Construct object
Constructs an ostream object.
(1) inititalization constructor
Assigns initial values to the components of its base classes by calling the inherited member ios::init with sb as argument.
(2) copy constructor (deleted)
Deleted: no copy constructor.
(3) move constructor (protected)
Acquires the contents of x, except its associated stream buffer: It calls ios::move to transfer x's internal components inherited from ios. x is left with its associated stream buffer unchanged and not tied (all other components of x are in an unspecified but valid state after the call).
,故故不能复制构造,且如果返回的不是iostream的引用,而是void,则无法连续输出对象;再者,
iostream的使用就是读写过程,不能用const进行限制。而对应的,若使用友元重载,
则另外一个参数const与否要考虑实际。
2.无论是友元还是成员重载++,后驱形式的参数int都不能给实际传值类型,只能写int ;不能写成int x或者int x=0 形式,此参数只作为区分的作用,若写成后面的形式,会引起编译错误
3.对输出输出流,按照习惯,只能写成友元的重载形式,但是,逻辑上也能写成成员重载,但非常反人类
因为逻辑上的成员重载,<<操作符号由左到右结合,由于需要this指针调用(必须一个类对象引起调用,形式为 Object.operator(argument...)形式, ),由此,cout不能写在左边,左边必须为类对象
即cout<<a<<b;如果用友元重载则 b<<(a<<cout);这种写法才行
如果要达到cout<<a<<b这种成员重载写法,只能改写(增加)std内的ostream 对象重载形式,这样会污染std空间