运算付重载只是一种语法上的修饰,为类的用户提供更方便的语法,这意味着它是另外一种调用函数的方法,函数的调用者和参数往往是对象,也就是说重载后的运算符表示了一种对象的“运算”操作。
1.语法
定义一个运算符就像定义一个函数,只是该函数的名字是operator@(@代表运算符的名称),要注意两个东西:
*运算符是一元的还是二元的
*运算符被定义成全局函数(对于一元是一个参数,二元是两个参数)还是成员函数(对于一元没有参数,对于二元两个参数,对象变为左侧参数)
*不能重载的运算符:'.','.*'(成员指针逆向引用运算符),不能编写目前运算符集合中没有的运算符,不能这样做的原因是难以确定其优先级
2.非成员运算符
成员运算符强调了运算符和类的集合,但是有时左侧运算符是别的类的对象,这时就要使用非成员运算符,非成员运算符提供了更大的灵活性。一般将其声明为类的一个friend函数
class a
{
...
friend ** operator@ (**);
};
friend ** operator@ (**)
{
...
}
3.重载赋值符
“=”经常会在c++中引起混乱,它有时候是最基本的寄存器的拷贝,有时则会调用拷贝构造函数等等。
当“=”被重载时,要记住这样一个差别:
如果对象还没有被创建,需要的则是初始化(如调用拷贝构造函数),否则就使用赋值运算符的重载形式
eg:
foo B;
foo A = B;(调用拷贝构造函数)
A = B; (使用重载的运算符)
4.自动类型转换
在c++中,如果编译器看到一个表达式或函数使用了一个不合适的类型,它经常会执行一个自动类型转换。
一般有两种技术:构造函数技术,运算符技术。
eg:
构造函数技术:
class one
{
int x;
public:
one(){}
//operator two() const {return two(x);} //运算符技术
};
class two
{
int i;
public: two(const one&) {}
};
void f(two)
{}
main()
{
one One;
f(One);
}
用构造函数技术,目的类执行转换,然后使用运算符技术,是源类执行转换。
5.应用
*聪明指针
定义一个类obj,定义一个装载obj的类obj_container,并在其中定义一个友元类sp,类sp中包含指向obj_container的指针,通过重载运算符“++”,“->”,使得类sp看起来像一个聪明的指针,可以使用“++”向前移动它,它不会超出包容器(obj_container)的范围,并可以通过“->”返回它指向的内容,以一种直接的方式实现了一种其实隔了好多层的调用,使得语法上非常清楚。
阅读(797) | 评论(0) | 转发(0) |