运算符重载
在C++中会把运算符当作函数来处理,当我们使用运算符时,编译器其实是把运算符翻译成函数,由于C++支持函数重载,所以C++中的运算符也是可以重载的,这样可以对类对象进行定制操作,从而简化操作、提高代码的可读性,如:string类就一个支持众多运算符的字符串类。
Class A
{
};
A a,b;
当对象支持+运算符时:a + b;
成员函数:
const A& operator+(const A& b);
全局函数:
const A& operator+(const A& a,const B& b)
注意:全局运算符函数中可能会访问到类的私有、保护的成员变量,C++提供的解决方案是把全局运算符函数声明为类的友元函数,那么在友元函数中就可以访问类的私有、保护类的成员。
友元:在类的外部某个函数中想访问类的私有、保护类成员,需要把函数声明为类的友云函数,但友元仅仅是朋友,它只有访问权没有拥有权(没有this指针)。
友元声明:把函数的声明写到类中一份,并在函数的声明前加上friend关键字,使用友元可以确保类的封装性。
注意:友元函数不会与成员函数构成重载,因为它们不在一个作用域内,但依然可能会冲突。
输入输出运算符重载
1、cout 是ostream类型对象,cin是istream类型对象。
2、当我们想让类对象方便使用cout/cin输入输出时就需要把它们的<</>>运算符进行重载。
3、根据双目运算符的解析规则,如果重载为成员函数,则函数的调用者为cout/cin,但我无法到ostream/istream类中修改代码,因此只能重载为全局函数。
ostream& operator<<(ostream& os const A a)
{
}
istream& operator>>(istream& is conat A a)
{
}
注意:在输入输出过程中,cin/cout会记录错误、状态标志,所以不能const属性。
赋值类型运算符重载
void operator=(const A& b)
{
}
1、注意赋值运算符的调用
A a = val; // 调用单参构造
a = b; // 调用赋值运算符
注意:一般不需要重写赋值运算符,类中有缺省的赋值运算符,当需要深拷贝时才需要显示实现。
单目运算符的重载
成员函数:
[const] A operator#(void)[const]
{
}
全局函数:
[const] A operator#([const] A& that)
{
}
前--/++:
A& operator++(void)
{
}
A& operator++(A& that)
{
}
后--/++(哑元):
A operator++(int)
{
}
A operator++(A& that,int)
{
}
注意:前自变与后自变的参数基本一样,唯的区别是哑元。
特殊运算符的重载
[] 下标运算符,重载了它类对象可以伪装成数组使用,STL模板库大多数容器都重载了它。
() 函数操作运算符,重载了它类对象可以伪装成函数使用。
* 解引用运算符,-> 成员访问运算符,重载了它类对象可以伪装成指针使用,STL中的智能指针就是通过重载它们实现的。