C++ 重载运算符和重载函数
C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。
重载声明 是指一个 与之前已经在该作用域内声明过的函数或方法 具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。
当您调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。
选择最合适的重载函数或重载运算符的过程,称为重载决策。
C++ 中的函数重载
在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。
您不能仅通过返回类型的不同来重载函数。
下面的实例中,同名函数 print() 被用于输出不同的数据类型:
#include <iostream>
using namespace std;
class printData
{
public:
void print(int i) {
cout << "Printing int: " << i << endl;
}
void print(double f) {
cout << "Printing float: " << f << endl;
}
void print(char* c) {
cout << "Printing character: " << c << endl;
}
};
int main(void)
{
printData pd;
// Call print to print integer
pd.print(5);
// Call print to print float
pd.print(500.263);
// Call print to print character
pd.print("Hello C++");
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Printing int: 5
Printing float: 500.263
Printing character: Hello C++
#include <iostream>
#include <cstring>
using namespace std;
class BeyondSmartShow
{
public:
void show(int i);
// 函数重载
void show(string str);
// 函数重载
void show(char c);
};
void BeyondSmartShow::show(int i)
{
cout << "int: " << i << endl;
}
void BeyondSmartShow::show(string str)
{
cout << "string: " << str << endl;
}
void BeyondSmartShow::show(char c)
{
cout << "char : " << c << endl;
}
int main ()
{
BeyondSmartShow beyondShow;
beyondShow.show(67);
beyondShow.show("未闻花名");
beyondShow.show('X');
return 0;
}
C++ 中的运算符重载
您可以重定义或重载绝大部分 C++ 内置的运算符。这样,您就能使用自定义类型的运算符。
重载的运算符是带有特殊名称的函数,函数名是由关键字operator 和其后要重载的运算符符号构成的。
与其他函数一样,重载运算符有一个返回类型和一个参数列表。
Box operator+(const Box&);
声明加法运算符用于把两个 Box 对象相加,返回最终的 Box 对象。
大多数的重载运算符可被定义为普通的非成员函数或者被定义为类成员函数。
如果我们定义上面的函数为类的非成员函数,那么我们需要为每次操作传递两个参数,如下所示:
Box operator+(const Box&, const Box&);
下面的实例使用成员函数演示了运算符重载的概念。
在这里,对象作为参数进行传递,对象的属性使用 this 运算符进行访问,如下所示:
#include <iostream>
using namespace std;
class Box
{
public:
double getVolume(void)
{
return length * breadth * height;
}
void setLength( double len )
{
length = len;
}
void setBreadth( double bre )
{
breadth = bre;
}
void setHeight( double hei )
{
height = hei;
}
// 重载 + 运算符,用于把两个 Box 对象相加
Box operator+(const Box& b)
{
Box box;
box.length = this->length + b.length;
box.breadth = this->breadth + b.breadth;
box.height = this->height + b.height;
return box;
}
private:
double length; // 长度
double breadth; // 宽度
double height; // 高度
};
// 程序的主函数
int main( )
{
Box Box1; // 声明 Box1,类型为 Box
Box Box2; // 声明 Box2,类型为 Box
Box Box3; // 声明 Box3,类型为 Box
double volume = 0.0; // 把体积存储在该变量中
// Box1 详述
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
// Box2 详述
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
// Box1 的体积
volume = Box1.getVolume();
cout << "Volume of Box1 : " << volume <<endl;
// Box2 的体积
volume = Box2.getVolume();
cout << "Volume of Box2 : " << volume <<endl;
// 把两个对象相加,得到 Box3
Box3 = Box1 + Box2;
// Box3 的体积
volume = Box3.getVolume();
cout << "Volume of Box3 : " << volume <<endl;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Volume of Box1 : 210
Volume of Box2 : 1560
Volume of Box3 : 5400
#include <iostream>
using namespace std;
// 重载运算符 +
class Cube
{
private:
double _length;
double _width;
double _height;
public:
// 声明设置长宽高
void set3DSize(double length,double width,double height);
// 获取体积
double giveResult();
// 重载 + 运算符
Cube operator+(const Cube& oneCube);
};
// 千万不要忘记这个 Cube::
// 重载 + 运算符
Cube Cube::operator+(const Cube& oneCube)
{
Cube tmpCube;
tmpCube._length = this->_length + oneCube._length;
tmpCube._width = this->_width + oneCube._width;
tmpCube._height = this->_height + oneCube._height;
return tmpCube;
}
// 千万不要忘记这个 Cube::
void Cube::set3DSize(double length,double width,double height)
{
_length = length;
_width = width;
_height = height;
}
// 千万不要忘记这个 Cube::
double Cube::giveResult()
{
return _length * _width * _height;
}
int main ()
{
Cube cube_1;
cube_1.set3DSize(5,6,7);
Cube cube_2;
cube_2.set3DSize(1,2,3);
Cube resultCube = cube_1 + cube_2;
cout << resultCube.giveResult() << endl;
return 0;
}
可重载运算符/不可重载运算符
下面是可重载的运算符列表:
+ | - | * | / | % | ^ |
& | | | ~ | ! | , | = |
< | > | <= | >= | ++ | -- |
<< | >> | == | != | && | || |
+= | -= | /= | %= | ^= | &= |
|= | *= | <<= | >>= | [] | () |
-> | ->* | new | new [] | delete | delete [] |
下面是不可重载的运算符列表:
:: | .* | . | ?: |
运算符重载实例
下面提供了各种运算符重载的实例,帮助您更好地理解重载的概念。
序号 | 运算符和实例 |
---|---|
1 | 一元运算符重载 |
2 | 二元运算符重载 |
3 | 关系运算符重载 |
4 | 输入/输出运算符重载 |
5 | ++ 和 -- 运算符重载 |
6 | 赋值运算符重载 |
7 | 函数调用运算符 () 重载 |
8 | 下标运算符 [] 重载 |
9 | 类成员访问运算符 -> 重载 |
C++ 一元运算符重载
一元运算符只对一个操作数进行操作,下面是一元运算符的实例:
- 递增运算符( ++ )和递减运算符( -- )
- 一元减运算符,即负号( - )
- 逻辑非运算符( ! )
一元运算符通常出现在它们所操作的对象的左边,比如 !obj、-obj 和 ++obj,但有时它们也可以作为后缀,比如 obj++ 或 obj--。
下面的实例演示了如何重载一元减运算符( - )。
#include <iostream>
using namespace std;
class Distance
{
private:
int feet; // 0 到无穷
int inches; // 0 到 12
public:
// 所需的构造函数
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
// 显示距离的方法
void displayDistance()
{
cout << "F: " << feet << " I:" << inches <<endl;
}
// 重载负运算符( - )
Distance operator- ()
{
feet = -feet;
inches = -inches;
return Distance(feet, inches);
}
};
int main()
{
Distance D1(11, 10), D2(-5, 11);
-D1; // 取相反数
D1.displayDistance(); // 距离 D1
-D2; // 取相反数
D2.displayDistance(); // 距离 D2
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
F: -11 I:-10
F: 5 I:-11
希望上面的实例能够帮您更好地理解一元运算符重载的概念,类似地,您可以尝试重载逻辑非运算符( ! )。
代码如下:
#include <iostream>
using namespace std;
// 重载一元运算符 -
class Point
{
private:
int _x;
int _y;
public:
//构造函数
Point();
Point(int x,int y);
// 显示
void show();
// 重载一元运算符 -
// 因为是一元,所以没有参数
Point operator-();
};
// 定义函数
Point::Point()
{
_x = 0;
_y = 0;
}
Point::Point(int x,int y)
{
_x = x;
_y = y;
}
void Point::show()
{
cout << "x is: " << _x << ",y is: " << _y << endl;
}
Point Point::operator-()
{
_x = -_x;
_y = -_y;
return Point(_x,_y);
}
int main ()
{
Point point_1(6,7);
point_1.show();
-point_1;
point_1.show();
return 0;
}
效果如下:
C++ 二元运算符重载
二元运算符需要两个参数,下面是二元运算符的实例。
我们平常使用的加运算符( + )、减运算符( - )、乘运算符( * )和除运算符( / )都属于二元运算符。就像加(+)运算符。
下面的实例演示了如何重载加运算符( + )。类似地,您也可以尝试重载减运算符( - )和除运算符( / )。
#include <iostream>
using namespace std;
class Box
{
double length; // 长度
double breadth; // 宽度
double height; // 高度
public:
double getVolume(void)
{
return length * breadth * height;
}
void setLength( double len )
{
length = len;
}
void setBreadth( double bre )
{
breadth = bre;
}
void setHeight( double hei )
{
height = hei;
}
// 重载 + 运算符,用于把两个 Box 对象相加
Box operator+(const Box& b)
{
Box box;
box.length = this->length + b.length;
box.breadth = this->breadth + b.breadth;
box.height = this->height + b.height;
return box;
}
};
// 程序的主函数
int main( )
{
Box Box1; // 声明 Box1,类型为 Box
Box Box2; // 声明 Box2,类型为 Box
Box Box3; // 声明 Box3,类型为 Box
double volume = 0.0; // 把体积存储在该变量中
// Box1 详述
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
// Box2 详述
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
// Box1 的体积
volume = Box1.getVolume();
cout << "Volume of Box1 : " << volume <<endl;
// Box2 的体积
volume = Box2.getVolume();
cout << "Volume of Box2 : " << volume <<endl;
// 把两个对象相加,得到 Box3
Box3 = Box1 + Box2;
// Box3 的体积
volume = Box3.getVolume();
cout << "Volume of Box3 : " << volume <<endl;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Volume of Box1 : 210
Volume of Box2 : 1560
Volume of Box3 : 5400
代码如下:
#include <iostream>
using namespace std;
// 重载+号
// 正方形
class Square
{
private:
int _length;
public:
void setLength(int length);
int getLength();
int getArea();
// 重载 + 号
Square operator+(const Square& otherSquare);
};
// 重载 + 号
Square Square::operator+(const Square& otherSquare)
{
Square result;
// 这儿一个用this->, 另一个必须用 点号运算符
result.setLength(this->_length + otherSquare._length);
return result;
}
void Square::setLength(int length)
{
_length = length;
}
int Square::getLength()
{
return _length;
}
int Square::getArea()
{
return _length * _length;
}
int main ()
{
Square square_01;
square_01.setLength(6);
cout << square_01.getArea() << endl;
Square square_02;
square_02.setLength(7);
cout << square_02.getArea() << endl;
Square square_03;
square_03 = square_01 + square_02;
cout << square_03.getArea() << endl;
return 0;
}
运行效果如下:
C++ 关系运算符重载
C++ 语言支持各种关系运算符( < 、 > 、 <= 、 >= 、 == 等等),它们可用于比较 C++ 内置的数据类型。
您可以重载任何一个关系运算符,重载后的关系运算符可用于比较类的对象。
下面的实例演示了如何重载 < 运算符,类似地,您也可以尝试重载其他的关系运算符。
#include <iostream>
using namespace std;
class Distance
{
private:
int feet; // 0 到无穷
int inches; // 0 到 12
public:
// 所需的构造函数
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
// 显示距离的方法
void displayDistance()
{
cout << "F: " << feet << " I:" << inches <<endl;
}
// 重载负运算符( - )
Distance operator- ()
{
feet = -feet;
inches = -inches;
return Distance(feet, inches);
}
// 重载小于运算符( < )
bool operator <(const Distance& d)
{
if(feet < d.feet)
{
return true;
}
if(feet == d.feet && inches < d.inches)
{
return true;
}
return false;
}
};
int main()
{
Distance D1(11, 10), D2(5, 11);
if( D1 < D2 )
{
cout << "D1 is less than D2 " << endl;
}
else
{
cout << "D2 is less than D1 " << endl;
}
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
D2 is less than D1
重载 > ,对比身高,代码如下:
#include <iostream>
#include <cstring>
using namespace std;
class Girl
{
private:
// 身高
int _heigth;
public:
void setHeight(int height);
// 重载运算符 > 的声明部分
bool operator>(const Girl& cuteGirl);
};
// 重载运算符 > 的定义部分
bool Girl::operator>(const Girl& cuteGirl)
{
return (this->_heigth > cuteGirl._heigth);
}
void Girl::setHeight(int height)
{
_heigth = height;
}
int main ()
{
Girl girl_1;
girl_1.setHeight(163);
Girl girl_2;
girl_2.setHeight(168);
// 第2个女孩 是不是 比第1个要高
cout << (girl_2 > girl_1) << endl;
return 0;
}
重载 < 代码如下:
#include <iostream>
using namespace std;
// 重载 < 号
class Point
{
private:
int _x;
int _y;
public:
// 构造函数
Point();
Point(int x,int y);
void show();
// 重载一元运算符,与自己斗其乐无穷
Point operator-();
// 重载二元运算符 < ,与另一对象斗其乐无穷
bool operator<(const Point& otherPoint);
};
// 重载一元运算符,与自身做对
Point Point::operator-()
{
return Point(-_x,-_y);
}
// 重载二元运算符 < ,与另一对象斗其乐无穷
bool Point::operator<(const Point& otherPoint)
{
int _distance = this->_x * this->_x + this->_y * this->_y;
int otherDistance = otherPoint._x * otherPoint._x + otherPoint._y * otherPoint._y;
if(_distance < otherDistance){
cout << this->_x << "," << this->_y << " のdistance:" << _distance << " < " << otherPoint._x << "," << otherPoint._y << "のdistance:" << otherDistance << endl;
return true;
}else{
cout << this->_x << "," << this->_y << " のdistance:" << _distance << " > " << otherPoint._x << "," << otherPoint._y << "のdistance:" << otherDistance << endl;
return false;
}
}
// 构造函数
Point::Point()
{
_x = 0;
_y = 0;
}
Point::Point(int x,int y)
{
_x = x;
_y = y;
}
void Point::show()
{
cout << _x << "," << _y << endl;
}
int main ()
{
Point point_0(13,14);
point_0.show();
Point rePoint_0 = -point_0;
rePoint_0.show();
Point point_1(5,8);
point_1.show();
Point point_2(6,7);
point_2.show();
cout << (point_1 < point_2) << endl;
return 0;
}
效果如下:
C++ 输入/输出运算符重载
C++ 能够使用流提取运算符 >> 和流插入运算符 <<来 输入和输出内置的数据类型。
您可以重载流提取运算符>>和流插入运算符<<来操作对象等用户自定义的数据类型。
在这里,有一点很重要,我们需要把运算符重载函数声明为类的友元函数,这样我们就能不用创建对象而直接调用函数。
下面的实例演示了如何重载提取运算符 >> 和插入运算符 <<。
#include <iostream>
using namespace std;
class Distance
{
private:
int feet; // 0 到无穷
int inches; // 0 到 12
public:
// 所需的构造函数
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
friend ostream &operator<<( ostream &output,
const Distance &D )
{
output << "F : " << D.feet << " I : " << D.inches;
return output;
}
friend istream &operator>>( istream &input, Distance &D )
{
input >> D.feet >> D.inches;
return input;
}
};
int main()
{
Distance D1(11, 10), D2(5, 11), D3;
cout << "Enter the value of object : " << endl;
cin >> D3;
cout << "First Distance : " << D1 << endl;
cout << "Second Distance :" << D2 << endl;
cout << "Third Distance :" << D3 << endl;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
$./a.out
Enter the value of object :
70
10
First Distance : F : 11 I : 10
Second Distance :F : 5 I : 11
Third Distance :F : 70 I : 10
重载流输入>>和流输出<<,代码如下:
#include <iostream>
using namespace std;
// 重载 >> 和 << 难点!
class Point
{
private:
int _x;
int _y;
public:
// 两个构造函数
Point();
Point(int x,int y);
// 重载 >> 和 << 的操作数只有两个!
// 所以必须声明为友元函数,而不是成员函数
// 如果是成员函数,那么就有3个操作数了!
// 因为流要连续输出,所以必须要返回引用,参数也是引用
friend ostream &operator<<(ostream &os,const Point& onePoint);
// 因为流要连续输入,所以必须要返回引用,参数也是引用
friend istream &operator>>(istream &is,Point &targetPoint);
};
// 因为定义的是友元函数,所以函数名前面千万不要再添加Point::范围解析运算符了
// 因为流要连续输出,所以必须要返回引用,参数也是引用
ostream& operator<<(ostream &os,const Point& onePoint)
{
os << onePoint._x << "," << onePoint._y << endl;
return os;
}
// 因为流要连续输入,所以必须要返回引用,参数也是引用
istream &operator>>(istream &is,Point &targetPoint)
{
is >> targetPoint._x >> targetPoint._y;
return is;
}
Point::Point()
{
_x = 0;
_y = 0;
}
Point::Point(int x,int y)
{
_x = x;
_y = y;
}
int main ()
{
Point point_01(6,7);
cout << point_01 << endl;
Point newPoint;
// 读取,并存入类Point的对象_x,和_y中
cin >> newPoint;
cout << newPoint << endl;
return 0;
}
运行效果如下:
C++ ++ 和 -- 运算符重载
递增运算符( ++ )和递减运算符( -- )是 C++ 语言中两个重要的一元运算符。
下面的实例演示了如何重载递增运算符( ++ ),包括前缀和后缀两种用法。
类似地,您也可以尝试重载递减运算符( -- )。
#include <iostream>
using namespace std;
class Time
{
private:
int hours; // 0 到 23
int minutes; // 0 到 59
public:
// 所需的构造函数
Time(){
hours = 0;
minutes = 0;
}
Time(int h, int m){
hours = h;
minutes = m;
}
// 显示时间的方法
void displayTime()
{
cout << "H: " << hours << " M:" << minutes <<endl;
}
// 重载前缀递增运算符( ++ )
Time operator++ ()
{
++minutes; // 对象加 1
if(minutes >= 60)
{
++hours;
minutes -= 60;
}
return Time(hours, minutes);
}
// 重载后缀递增运算符( ++ )
Time operator++( int )
{
// 保存原始值
Time T(hours, minutes);
// 对象加 1
++minutes;
if(minutes >= 60)
{
++hours;
minutes -= 60;
}
// 返回旧的原始值
return T;
}
};
int main()
{
Time T1(11, 59), T2(10,40);
++T1; // T1 加 1
T1.displayTime(); // 显示 T1
++T1; // T1 再加 1
T1.displayTime(); // 显示 T1
T2++; // T2 加 1
T2.displayTime(); // 显示 T2
T2++; // T2 再加 1
T2.displayTime(); // 显示 T2
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
H: 12 M:0
H: 12 M:1
H: 10 M:41
H: 10 M:42重载
重载前缀自增++ 和 后缀自增++代码如下:
#include <iostream>
#include <iomanip>
using namespace std;
// 重载前缀自增和后缀自增
class Time{
private:
int _hour; // 0-23
int _minute; // 0-59
public:
//构造函数
Time();
Time(int hour,int minute);
// 重载前缀自增 ++t (自增1分)
Time operator++();
// 重载后缀自增 t++ (有参与运算的参数)
Time operator++(int );
// 显示
void show();
};
// 重载前缀自增 ++t (自增1分)
Time Time::operator++()
{
int tmpMin = ++_minute;
if (tmpMin > 59)
{
_minute = 0;
_hour = _hour + 1;
if (_hour > 23)
{
_hour = 0;
}
}
Time result(_hour,_minute);
return result;
}
// 重载后缀自增 t++ (有参与运算的参数)
Time Time::operator++(int )
{
// 先用局部变量保存,用来返回结果;然后再更新对象内部的成员
Time tmpReturn(_hour,_minute);
int tmpMin = _minute + 1;
if (tmpMin > 59)
{
_minute = 0;
_hour = _hour + 1;
if (_hour > 23)
{
_hour = 0;
}
}
return tmpReturn;
}
void Time::show()
{
// 设置宽为2,如果不够就用0补位
cout << setfill('0')<< setw(2) << _hour << ":" ;
// 设置宽为2,如果不够就用0补位
cout << setfill('0')<< setw(2) << _minute << endl;
}
Time::Time()
{
_hour = 0;
_minute = 0;
}
Time::Time(int hour,int minute)
{
_hour = hour;
_minute = minute;
}
int main ()
{
Time timeNow(13,59);
timeNow.show();
++timeNow;
timeNow.show();
Time time_2(14,59);
time_2++.show();
time_2.show();
return 0;
}
运行效果如下:
C++ 赋值运算符重载
就像其他运算符一样,您可以重载赋值运算符( = ),用于创建一个对象,比如拷贝构造函数。
下面的实例演示了如何重载赋值运算符。
#include <iostream>
using namespace std;
class Distance
{
private:
int feet; // 0 到无穷
int inches; // 0 到 12
public:
// 所需的构造函数
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
void operator=(const Distance &D )
{
feet = D.feet;
inches = D.inches;
}
// 显示距离的方法
void displayDistance()
{
cout << "F: " << feet << " I:" << inches << endl;
}
};
int main()
{
Distance D1(11, 10), D2(5, 11);
cout << "First Distance : ";
D1.displayDistance();
cout << "Second Distance :";
D2.displayDistance();
// 使用赋值运算符
D1 = D2;
cout << "First Distance :";
D1.displayDistance();
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
First Distance : F: 11 I:10
Second Distance :F: 5 I:11
First Distance :F: 5 I:11
重载 = 的代码如下:
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;
// 重载 =
class Girl
{
private:
// 罩杯
char _cup;
int _age;
string _name;
public:
Girl();
Girl(string name,int age,char cup);
void show();
// 重载 =
void operator=(const Girl& otherGirl);
};
// 重载 =
void Girl::operator=(const Girl& otherGirl)
{
_name = otherGirl._name;
// 刚克隆出来的Girl 年龄为0
_age = 0;
_cup = otherGirl._cup;
}
void Girl::show()
{
cout << "芳名:" << _name << ",芳龄:" << _age << ",罩杯:" << _cup << endl;
}
Girl::Girl(string name,int age,char cup)
{
_cup = cup;
_age = age;
_name = name;
}
Girl::Girl()
{
_name = "";
_age = 0;
_cup = ' ';
}
int main ()
{
Girl cutePrincess("茜",16,'E');
cutePrincess.show();
// 克隆一个
Girl cloneGirl;
cloneGirl = cutePrincess;
cloneGirl.show();
return 0;
}
运行效果如下:
C++ 函数调用运算符 () 重载
函数调用运算符 () 可以被重载用于类的对象。
当重载 () 时,您不是创造了一种新的调用函数的方式,相反地,这是创建一个 可以传递任意数目参数 的运算符函数。???Excuse Me???有什么用,有什么意义???
下面的实例演示了如何重载函数调用运算符 ()。
#include <iostream>
using namespace std;
class Distance
{
private:
int feet; // 0 到无穷
int inches; // 0 到 12
public:
// 所需的构造函数
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
// 重载函数调用运算符
Distance operator()(int a, int b, int c)
{
Distance D;
// 进行随机计算
D.feet = a + c + 10;
D.inches = b + c + 100 ;
return D;
}
// 显示距离的方法
void displayDistance()
{
cout << "F: " << feet << " I:" << inches << endl;
}
};
int main()
{
Distance D1(11, 10), D2;
cout << "First Distance : ";
D1.displayDistance();
D2 = D1(10, 10, 10); // invoke operator()
cout << "Second Distance :";
D2.displayDistance();
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
First Distance : F: 11 I:10
Second Distance :F: 30 I:120
重载 () 的代码如下:
#include <iostream>
using namespace std;
class Point
{
private:
int _x;
int _y;
public:
Point();
Point(int x,int y);
// 重载 (),但不知有何用处
Point operator()(int var_1,int var_2,int var_3);
void show();
};
// 重载 (),但不知有何用处
Point Point::operator()(int var_1,int var_2,int var_3)
{
Point resultPoint;
resultPoint._x = var_1 + var_2;
resultPoint._y = var_2 + var_3;
return resultPoint;
}
Point::Point()
{
_x = 0;
_y = 0;
}
Point::Point(int x,int y)
{
_x = x;
_y = y;
}
void Point::show()
{
cout << _x << "," << _y<< endl;
}
int main ()
{
Point point_1(6,7);
point_1.show();
Point point_2;
// 有什么意义???跟point_1._x和point_1._y根本没有关系嘛
point_2 = point_1(1,2,3);
point_2.show();
return 0;
}
运行效果如下:
C++ 下标运算符 [] 重载
下标操作符 [] 通常用于访问数组元素。重载该运算符用于增强操作 C++ 数组的功能。
下面的实例演示了如何重载下标运算符 []。
#include <iostream>
using namespace std;
const int SIZE = 10;
class safearay
{
private:
int arr[SIZE];
public:
safearay()
{
register int i;
for(i = 0; i < SIZE; i++)
{
arr[i] = i;
}
}
int& operator[](int i)
{
if( i > SIZE )
{
cout << "索引超过最大值" <<endl;
// 返回第一个元素
return arr[0];
}
return arr[i];
}
};
int main()
{
safearay A;
cout << "A[2] 的值为 : " << A[2] <<endl;
cout << "A[5] 的值为 : " << A[5]<<endl;
cout << "A[12] 的值为 : " << A[12]<<endl;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
$ g++ -o test test.cpp
$ ./test
A[2] 的值为 : 2
A[5] 的值为 : 5
A[12] 的值为 : 索引超过最大值
0
重载 [] 代码如下:
#include <iostream>
using namespace std;
const int LEN = 5;
// 自律型的数组(自带边界检查)
class SelfDisciplineArray
{
private:
// 内部维护一个数组
int _array[LEN];
public:
// 构造方法
SelfDisciplineArray();
// 重载[]
int &operator[](int index);
};
// 重载[] ,返回值为啥要变成 引用???
int& SelfDisciplineArray::operator[](int index)
{
if (index >= LEN)
{
cout << "数组越界 ";
// 既然越界了,为啥还要返回 _array[0]???
return _array[0];
}else{
return _array[index];
}
}
// 构造方法,初始化
SelfDisciplineArray::SelfDisciplineArray()
{
for (int i = 0; i < LEN; ++i){
_array[i] = i;
}
}
int main ()
{
SelfDisciplineArray arr_1;
cout << arr_1[3] << endl;
cout << arr_1[5] << endl;
return 0;
}
运行效果:
C++ 类成员访问运算符 -> 重载
类成员访问运算符( -> )可以被重载,但它较为麻烦。
它被定义用于为一个类赋予"指针"行为。
运算符 -> 必须是一个成员函数。
如果使用了 -> 运算符,返回类型必须是指针或者是类的对象。
运算符 -> 通常与指针引用运算符 *结合使用,用于实现"智能指针"的功能。
这些指针是行为与正常指针相似的对象,唯一不同的是,当您通过指针访问对象时,它们会执行其他的任务。
比如,当指针销毁时,或者当指针指向另一个对象时,会多此一举,自作聪明地 自动删除对象。
间接引用运算符 -> 可被定义为一个一元后缀运算符。也就是说,给出一个类:
class Ptr{
//...
X * operator->();
};
类 Ptr 的对象 可以 访问另一个类 X 的成员,使用方式与指针的用法十分相似。例如:
void f(Ptr p )
{
p->m = 10 ; // (p.operator->())->m = 10
}
语句 p->m 被解释为 (p.operator->())->m。
The structure dereference operator (->) overload is a special case of operator overloading. The operator is actually invoked in a loop until a real pointer is returned, and then that real pointer is dereferenced. Suppose you had the following classes:
struct A {
int foo, bar;
};
struct B {
A a;
A *operator->() { return &a; }
};
struct C {
B b;
B operator->() { return b; }
};
struct D {
C c;
C operator->() { return c; }
};
If you had an object d of type D, calling d->bar would first call D::operator->(), then C::operator->(), and then B::operator->(), which finally returns a real pointer to struct A, and its bar member is dereferenced (被间接引用的) in the normal manner. Note that in the following:
struct E1 {
int foo, bar;
E1 operator->() { return *this; }
};
Calling e->bar, where e is of type E1, produces an infinite loop. If you wanted to actually dereference e.bar, you would need to do this:
struct E2 {
int foo, bar;
E2 *operator->() { return this; }
};
同样地,下面的实例演示了如何重载类成员访问运算符 -> ??? Excuse Me??? 下面这份代码什么鬼???完全搞不懂!!
#include <iostream>
using namespace std;
#include <vector>
// 什么鬼!!!完全搞不懂!!!!
class Girl {
// 静态成员变量是个什么shit???
static int _shit;
public:
void showGirlShit() {
cout << "____girl's shit is:" << ++_shit << endl;
}
};
// 静态成员定义
// 静态成员变量是个什么shit???
int Girl::_shit = 0;
// 为上面的类实现一个容器
class BeyondContainer {
vector<Girl*> girlPointArr;
public:
void add(Girl* p)
{
cout << "2: " << p << endl;
girlPointArr.push_back(p);
}
friend class BeyondPointer;
};
// 实现智能指针,用于访问类 Obj 的成员
class BeyondPointer {
BeyondContainer _beyondContainer;
int _cursor;
public:
BeyondPointer(BeyondContainer& container)
{
_beyondContainer = container;
_cursor = 0;
}
// 重载运算符 ->
Girl* operator->() const
{
Girl *p = _beyondContainer.girlPointArr[_cursor];
cout << endl << "3, p:" << p << endl;
return p;
}
// 返回值表示列表结束
bool operator++() // 前缀版本
{
Girl *p = _beyondContainer.girlPointArr[_cursor];
int tmpSize = _beyondContainer.girlPointArr.size();
cout << "4:_cursor:" << _cursor << ", size:" << tmpSize << ",p:" << p << endl;
// 这个是什么鬼??? 为什么有时候打印结果还TMD不一样!!!???
if(_cursor >= tmpSize || p== 0){
return false;
}
++_cursor;
return true;
}
};
int main() {
const int maxSize = 5;
Girl girlArr[maxSize];
BeyondContainer container;
for(int i = 0; i < maxSize; i++)
{
Girl *p = &girlArr[i];
cout << "1: " << p << endl;
// 添加对象的地址
container.add(p);
}
BeyondPointer sp(container); // 创建一个迭代器
do {
sp->showGirlShit(); // 智能指针调用
} while(++sp); //重载了++
return 0;
}
当上面的代码被编译和执行时,它会产生下列两种随机出现的结果????