C++输入输出++操作符重载

 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空间

posted @ 2019-04-10 12:08  reshuffle  阅读(430)  评论(0编辑  收藏  举报