C++允许在同一个作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。
重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但他们的参数列表和定义(实现)不相同。
当调用一个重载函数或重载运算符时,编译器通过把函数所使用的参数类型和定义中的参数类型进行比较,决定选用最合适的定义。
选择最合适的重载函数或重载运算符的过程,称为重载决策。
C++函数重载
在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(参数个数,类型或者顺序)必须不同,不能仅通过返回类型的不同来重载函数。
/*** overload.cpp ***/ #include<iostream> using namespace std; class printData { public: void print(int i) { cout << "integer is : " << i << endl; } void print(double f) { cout << "flota is : " << f << endl; } void print(char c[]) { cout << "char is : " << c << endl; } }; int main() { printData pd; pd.print(5); pd.print(300.1); char c[] = "hello C++"; pd.print(c); return 0; }
运行结果:
exbot@ubuntu:~/wangqinghe/C++/20190807$ vim overload.cpp
exbot@ubuntu:~/wangqinghe/C++/20190807$ g++ overload.cpp -o overload
exbot@ubuntu:~/wangqinghe/C++/20190807$ ./overload
integer is : 5
flota is : 300.1
char is : hello C++
运算符重载:
我们可以重新定义或重在大部分C++内置的运算符。这样就可以使用自定义的运算符了。
重载的运算符是带有特殊名称的函数,函数名是由关键字operator和其后要重载的运算符号构成。和其他函数一样,重载运算符有一个返回类型和一个参数列表。
Box operator+(const Box&);
声明加法运算符用于把两个Box对象相加,返回最终的的Box对象。大多数重载运算符可被定义为普通的非成员函数或被定义为类成员函数。
如果我们定义上面的的函数为类的非成员函数,那么我们需要为每次操作传递两个参数。如下所示:
Box operator+(const Box&, const Box&);
下面实例中,对象作为参数进行传递,对象的属性使用this运算符进行访问:
/***
overfun.cpp
***/
#include<iostream>
using namespace std;
class Box
{
public:
Box(double l = 2.0,double b = 2.0,double h = 2.0)
{
length = l;
breadth = b;
height = h;
}
double getVolume()
{
return length*breadth*height;
}
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(3.3,1.2,1.5);
Box box2(8.5,6.0,2.0);
Box box3;
double volume = 0.0;
volume = box1.getVolume();
cout << "Volume of box1 : " << volume << endl;
volume = box2.getVolume();
cout << "Volume of box2 : " << volume << endl;
box3 = box1 + box2;
volume = box3.getVolume();
cout << "Volume of box3 : " << volume << endl;
return 0;
}
运行结果:
exbot@ubuntu:~/wangqinghe/C++/20190808$ g++ overfun.cpp -o overfun
exbot@ubuntu:~/wangqinghe/C++/20190808$ ./overfun
Volume of box1 : 5.94
Volume of box2 : 102
Volume of box3 : 297.36
可重载运算符:
双目算数运算符 |
+,-,*,/,% |
关系运算符 |
==,!=,<,>,<= ,>= |
逻辑运算符 |
|| , && , ! |
单目运算符 |
+(正),-(负),*(指针),&(取地址) |
自增自减运算符 |
++,-- |
位运算符 |
| , &,~,^, << , >> |
赋值运算符 |
=,+=,-=,*=,/=,%=,&=,|=,^=, <<=,>>= |
空间申请与释放 |
new,delete,new[].delete[] |
其他运算符 |
() (函数调用),->(成员访问, ,(逗号),[] (下标) |
不可重载运算符列表:
. |
成员访问运算符 |
.*,->* |
成员指针访问运算符 |
:: |
域运算符 |
seizeof |
长度运算符 |
?: |
条件运算符 |
# |
预处理符号 |
Attention:
- 运算重载符不可以改变语法结构
- 运算重载符不可以改变操作数个数
- 运算重载付不可以改变优先级
- 运算重载符不可以改变结合性
类重载、覆盖、重定义的区别:
重载指的是函数具有不同的参数列表,而函数名相同的函数。重载要求参数列表必须不同,比如参数的类型不同、参数的个数不同,参数的顺序不同。因为重载要求参数列表必须不同。(同一类中)
覆盖是存在类中,子类重写从基类继承过来的函数。被重写的函数不能是static的。必须是virtual的。但函数名、返回值、参数列表都必须和基类相同(发生在基类和子类)。
重定义也叫做隐藏,子类重新定义父类中有相同名称的非虚函数(参数列表可以不同)。(发生在子类和基类)。