#include<iostream> using namespace std; class Box{ private: int width; int height; public: Box(int w,int h){ width=w; height=h; }; Box(){ }; //重载函数 void getWidth(){ cout<<width; }; int getheight(){ return width; }; //重载运算符 Box operator +(const Box &b){ //定义一个Box Box b1; b1.width=this->width+b.width; b1.height=this->height+b.height; return b1; } }; int main(){ Box b1(1,2),b2(2,3),b3; b3=b1+b2; cout<<b3.getheight(); return 0; }
C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。
重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。
当您调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。
在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。您不能仅通过返回类型的不同来重载函数
重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。
Box operator+(const Box&);
大多数的重载运算符可被定义为普通的非成员函数或者被定义为类成员函数。如果我们定义上面的函数为类的非成员函数,那么我们需要为每次操作传递两个参数,如下所示:
Box operator+(const Box&, const Box&);
下面是不可重载的运算符列表:
- .:成员访问运算符
- .*, ->*:成员指针访问运算符
- :::域运算符
- sizeof:长度运算符
- ?::条件运算符
- #: 预处理符号
更多请参考这里边
一元运算符
一元运算符只对一个操作数进行操作,下面是一元运算符的实例:
- 递增运算符( ++ )和递减运算符( -- )
递增运算符( ++ )和递减运算符( -- )是 C++ 语言中两个重要的一元运算符。
下面的实例演示了如何重载递增运算符( ++ ),包括前缀和后缀两种用法。类似地,您也可以尝试重载递减运算符( -- )。
-
// 重载前缀递增运算符( ++ ) 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 x=4;
- int y=++x;
- int z=x++;
- 前者返回增加后的值
- 后置返回原始值
-
Time T1(11, 59), T2(10,40); ++T1; // T1 加 1 T1.displayTime(); // 显示 T1 ++T1; // T1 再加 1 T1.displayTime(); // 显示 T1 T2++;
-
#include<iostream> using namespace std; class Time{ private: int hours; int minutes; public: Time(int h,int m){ hours=h; minutes=m; } Time(){ } //重载函数先自增后赋值 Time operator++ (){ minutes++; if(minutes>=60){ hours++; if(hours>=24){ hours-=24; } if(minutes>=60){ minutes-=60; } } //传递一个Time实例回去 return Time(hours,minutes); } void getTime(){ cout<<hours<<endl; cout<<minutes; } }; int main(){ Time t(12,43); ++t; t.getTime(); return 0; }
注意一点:
-
在实例化不带参数的对象时 在你没有自定义带参构造函数时默认调用无参数构造函数 如果自定义带参构造函数 后边需要构造无参数对象就需要手动添加无参构造函数否则会报错
- box.length = this->length + b.length;前边这里使用的this可以去掉默认调用的是当前访问该函数的对象
- 一元减运算符,即负号( - )
-
// 重载负运算符( - ) Distance operator- () { feet = -feet; inches = -inches; return Distance(feet, inches); }
Distance D1(11, 10), D2(-5, 11);
-D1; // 取相反数 - 逻辑非运算符( ! )
特殊用法:
class A { private: int a; public: A(); A(int n); A operator+(const A & obj); A operator+(const int b); friend A operator+(const int b, A obj);
/*
因为其是全局函数,对应的参数个数为2。
当重载的运算符函数是全局函数时,需要在类中将该函数声明为友员。
*/ void display(); } ; A operator+(const int b, A obj) { return obj+b;//友元函数调用第二个重载+的成员函数 相当于 obj.operator+(b); (重点理解这里的) }
a3=a1+a2;//可以交换顺序,相当月a3=a1.operator+(a2);
a4=a1+m;//因为加了个友元函数所以也可以交换顺序了。 调用a4=a1.operator+(m)默认调用 A operator+(const int b); 如果改为a4=m+a1 则调用 friend A operator+(const int b, A obj); 返回 a1+m 效果等同于直接调用调用 A operator+(const int b)
输入输出运算符重载
friend ostream &operator<<( ostream &output, const Distance &D ) { output << "F : " << D.feet << " I : " << D.inches; return output; } //在类内部声明定义函数体友元函数的friend不是必须的 如果只是声明 在外部定义函数体需要添加friend friend istream &operator>>( istream &input, Distance &D )//注意这里的友元函数需要传递两个参数 自身以及参数 { input >> D.feet >> D.inches; return input; }
Distance D1(11, 10), D2(5, 11), D3; cout << "Enter the value of object : " << endl; cin >> D3;//调用 cin.operator >>(D3) 友元函数为 >>(cin,D3) cout << "First Distance : " << D1 << endl; cout << "Second Distance :" << D2 << endl; cout << "Third Distance :" << D3 << endl;
$./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
赋值运算符重载
void operator=(const Distance &D ) { feet = D.feet; inches = D.inches; }
// 使用赋值运算符 D1 = D2; cout << "First Distance :"; D1.displayDistance();
C++函数调用运算符()重载