函数重载
函数名相同,但函数类型、参数类型及个数不完全相同。本质上还是不同的函数,只不过方便记忆。
int add(int a, int b)
{
return a+b;
}
double add(double a, double b)
{
return a+b;
}
int add(int a, int b, int c)
{
return a+b+c;
}
多种构造函数均以类名为函数名(无参构造函数、有参构造函数、拷贝构造函数),但它们的参数不同,所以本质上也是函数重载。
运算符重载
由于类的对象无法使用+``-``*``/``>``<
这一类的运算符,故通过运算符重载,在类中赋予已有的运算符以新的意义,来解决这一问题
-
不能被重载的运算符:
.
:如a.print();
.*
:如a.*p;
::
:如Date::print();
?:
:如return (a>b)? a:b;
sizeof()
-
不建议被重载的运算符:
->
:如p->print();
->*
:如p->*pa;
,
&
()
注意事项
- 运算符重载时,运算符的“目数”不变,比如
+
需要两个数相加,重载后也必须是操作两个数,而不能是一个数或多个数; - 运算符重载时,优先级不变,比如重载后
+
的优先级还是低于*
的优先级; - 最好不要改变运算符的含义,比如强行把
+
重载成-
; - 不能创建新的运算符;
- 运算符的操作对象中,至少有一个是对象/对象引用;
- 重载运算符
()``[]``->``=
的时候,运算符重载函数必须是类的成员,而重载其他运算符的时候,运算符重载函数可以是类的友元函数; - 不可重载
int
、char
等已有类型的运算符; - 运算符重载是独立的,“推一步走一步”,不会自动产生“附加重载”,比如重载了
+
,但+=
不会被自动重载;
运算符重载-成员函数法
格式:类型名 operator 运算符 (参数){···}
。
一般“参数”最多有一个,常为常对象引用。如果没有参数,也不能省略()
例如,如果有一个复数类(包含实部和虚部),重载+
实现复数相加减
class Complex{
private:
double r,i;
public:
Complex(double R, double I){
r=R,i=I;
}
Complex operator + (const Complex &c)
{
return Complex(r+c.r, i+c.i);
//返回无名对象
}
};
运算符重载-友元函数法
格式:friend 类型名 operator 运算符 (参数){···}
这里的参数个数等于运算符的操作数个数,+
就是两个参数,++
则是一个参数。这里的参数也多为常对象引用
class Complex{
private:
double r,i;
public:
Complex(double R, double I){
r=R,i=I;
}
void print(){
cout<<r<<" "<<i;
}
friend Complex operator + (const Complex &c1, const Complex &c2);
};
Complex operator + (const Complex &c1, const Complex &c2){
return Complex(c1.r+c2.r, c1.i+c2.i);
}
通常情况下,双目运算符采用友元函数的方法,而单目运算符采用成员函数的方法。
重载<<
和>>
只能使用友元函数法,<<
对应ostream
类型,>>
对应istream
类型,一般有固定的格式可以套用
class inter{
private:
int a, b;
public:
friend istream& operator >> (istream &stream, inter &i);
friend ostream& operator << (ostream &stream, inter &i);
};
istream& operator >> (istream &stream, inter &i){
stream>>i.a>>i.b;
return stream;
}
ostream& operator << (ostream &stream, inter &i){
stream<<i.a<<" 2 "<<i.b<<endl;
return stream;
}
int main()
{
inter a;
cin>>a;
cout<<a;
return 0;
}