📄 08章 运算符重载.txt
字号:
class string {
friend bool operator!(const String&);
};
编程技巧8.6
重载一元运算符时,把运算符函数用作类的成员而不用作友元函数。因为友元的使用破坏了类的封装,所以除非绝对必要,否则应尽量避免使用友元函数和友元类。
8.7 重载二元运算符
二元运算符可以重载为带有一个参数的非static成员函数,或者带有两个参数的非成员函数(参数之—必须是类的对象或者是对类的对象的引用)。
本章稍后要重载运算符+=,当把它重载为带有一个参数的String类的非static成员函数时,如果y和z是String类的对象,则y == z将被处理为y.operator+=(z),调用成员函数operator+=,声明如下:
class String{
public:
const String&operator+=(const String &);
};
二元运算符+=也可以重载为带有两个参数的非成员函数,其中的一个参数必须是类的对象或者是对类的对象的引用。如果y和z是String类的对象,则y += z将被处理为operator+=(y,z),调用友元函数operator+=,声明如下:
class String{
friend const String&operator+=(String &,
const String &);
};
8.8 实例研究:Array类
在C和C++中,数组是一种指针,因而数组存在许多导致错误的陷阱。例如,由于C和C++不检测下标是否超出数组的边界而使程序导致越界错误;大小为n的数组的下标必须是0、1、2…、 n-1,下标是不允许改变的;不能一次入输人或输出整个数组,而只能单独读取或者输出每个数组元素;不能用相等运算符或者关系运算符比较两个数组(因为数组名仅仅是指向内存中数组起始位置的指针);当把一个数组传递给一个能处理任意大小数组的常用函数时,数组的大小也必须作为一个额外的参数传递给该函数;不能用赋值运算符把一个数组赋给另一个数组(因为数组名是const类型指针,而常量指针不能用于赋值运算符的左边)。尽管所有这些处理能力似乎应该是很自然的,但是C和C++都没有提供这种能力。然而,C++提供了实现这种能力的手段,这就是运算符重载。
本节的范例建立了一个数组类,它能检测范围以确保数组下标不会越界,允许用赋值运算符把一个数组赋给另外一个数组。数组对象自动知道数组的大小,因而不用将数组的大小传送给函数。可以用流读取运算符和流插入运算符输入输出整个数组。还可以用相等运算符==和!=比较数组。范例程序中的数组类用一个static成员跟踪程序中实例化数组对象的数目。
本例将加深读者对数据抽象的认识。当然,读者还可以增加数组类的其他功能,类的开发是十分有趣并富有挑战性的。
图8.4中的程序演示了类Array和用于该类的重载运算符。首先来看一下main函数中的驱动程序,然后再探讨类的定义以及类的每个成员和友元函数的定义。
1 // Fig. 8.4: arrayl.h
2 // Simple class Array (for integers}
3 #ifndef ARRAY1_H
4 #define ARRAY1_H
5
6 #include <iostream.h>
7
8 class Array {
9 friend ostream &operator<<( ostream &, const Array & );
l0 friend istream &operator>>( istream &, Array & );
11 public:
12 Array( int = 10 ); // default constructor
13 Array( const Array & ); // copy constructor
14 ~Array(); // destructor
15 int getSize() const; // return size
16 const Array &operator=( const Array & ); // assign arrays
17 bool operator==( const Array & ) const; // compare equal
18
19 // Determine if two arrays are not equal and
20 // return true, otherwise return false (uses operator==).
21 bool operator!=( const Array &right ) const
22 { return ! ( *this == right ); }
23
24 int &operator[] ( int ); // subscript operator
25 const int &operator[]( int ) const; // subscript operator
26 static int getArrayCount(); // Return count of
27 // arrays instantiated.
28 private:
29 int size; // size of the array
30 int *ptr; // pointer to first element of array
31 static int arrayCount; // # of Arrays instantiated
32 } ;
33
34 #endif
35 // Fig 8.4: arrayl.cpp
36 // Member function definitions for class Array
37 #include <iostream.h>
38 #include <iomanip.h>
39 #include <stdlib.h>
40 #include <assert.h>
41 #include "array1.h"
42
43 // Initialize static data member at file scope
44 int Array::arrayCount = 0; // no objects yet
45
46 // Default constructor for class Array (default size 10)
47 Array::Array( int arraySize )
48 {
49 size = ( arraySize > 0 ? arraySize : 10 );
50 ptr = new int[ size ] ; // create space for array
51 assert( ptr != 0 ); // terminate if memory not allocated
52 ++arrayCount; // count one more object
53
54 for (int i = 0; i < size; i++ )
55 ptr[ i ] = 0; // initialize array
56 }
57
58 // Copy constructor for class Array
59 // must receive a reference to prevent infinite recursion
60 Array::Array( const Array &init ) : size( intit.size )
61 {
62 ptr = new int[ size ] ; // create space for array
63 assert( ptr != 0 ); // terminate if memory not allocated
64 ++arrayCount; // count one more object
65
66 for (int i = 0; i < size; i++ )
67 ptr[ i ] init.ptr[ i ]; // copy init into object
68 }
69
70 // Destructor foi class Array
71 Array::~Array()
72 {
73 delete [] ptr; // reclaim space for array
74 --arrayCount; // one fewer objects
75 }
76
77 // Get the size of the array
78 int Array::getSize() const { return size; }
79
80 // Overloaded assignment operator
81 // const return avoids: ( al = a2 } = a3
82 const Array &Array::operator=( const Array &right )
83 {
84 if ( &right != this ) { // check for self-assignment
85
86 // for arrays of different sizes, deallocate original
87 // left side array, then allocate new left side array.
88 if ( size != right.size ) {
89 delete [] ptr; // reclaim space
90 size = right.size; // resize this object
91 ptr = new int[ size ]; // create space for array copy
92 assert( ptr != 0 ); // terminate if not allocated
93 }
94
95 for (int i = 0; i < size; i++ )
96 ptr[ i ] = right.ptr[ i ]; // copy array into object
97 }
98
99 return *this; // enables x = y = z;
100 }
101
102 // Determine if two arrays are equal and
103 // return true, otherwise return false.
104 bool Array::oprator==( const Array &right )const
105 {
106 if ( size != right.size )
107 return false; // arrays of different sizes
108
109 for (int i =0; i < size; i++ )
110 if ( ptr[ i ] != right.ptr[ i ] )
111 return false; // arrays are not equal
113 return true; // arrays are equal
114 }
117 // reference return creates an lvalue
118 int &Array::operator[] ( int subscript )
119 {
120 // check for subscript out of range error
121 assert( 0 <= subscript && subscript < size );
122
123 return ptr[ subscript ]; // reference return
124 }
125
126 // Overloaded subscript operator for const Arrays
127 // const reference return creates an value
128 const int &Array::operator[ ] (int subscript ) const
129 {
130 // check for subscript out of range error
131 assert( 0 <= subscript && subscript < size );
132
133 return ptr[ subscript ]; // const reference return
134 }
135
136 // Return the number of Array objects instantiated
137 // static functions cannot be const
138 int Array::getArrayCount() { return arrayCount; }
139
140 // Overloaded input operator for class Array;
141 // inputs values for entire array.
142 istream &operator>>( istream &input, Array &a )
143 {
144 for ( int i = 0; i < a.size; i++ )
145 input >> a.ptr[ i ];
146
147 return input; // enables cin >> x >> y;
148 }
149
150 // Overloaded output operator for class Array
151 ostream &operator<<( ostream &output, const Array &a )
152 {
153 int i;
154
155 for ( i = O; i < a.size; i++ ) {
156 output << setw( 12 ) << a.ptr[ i ];
157
158 if ( ( i + 1 ) % 4 == 0 ) // 4 numbers per row of output
159 output << endl;
160 }
161
162 if( i % 4 != 0 )
163 output << endl;
164
165 return output; // enables cout << ~ << y;
166 }
167 // Fig. 8.4:fig08 04.cpp
168 // Driver for simple class Array
169 #include <iostream.h>
170 #include "arrayl.h"
171
172 int main()
173 {
174 // no objects yet
175 cout << "# of arrays instantiated = "
176 << Array::getArrayCount() << '\n';
177
178 // create two arrays and print Array count
179 Array integers1( 7 ), integers2;
180 cout << "# of arrays instantiated = "
181 << Array::getArrayCount() << "\n\n";
182
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -