C++中重载箭头运算符详解

2018-01-26 10:30:46来源:网络收集作者:管理员人点击

分享

[var1]

首先看一个例子


#include
using namespace std;
class A
{
void fun()
{
cout << "amazing" << endl;
}
};
int main()
{
A a;
a->fun();//错误。“A”类型没有重载成员“operator ->”
system("pause");
return 0;
}一般来说,类对象不能使用箭头运算符访问成员函数,而应该使用点运算符。但是,如果该类重载了箭头运算符,则情况发生改变。


看下面这个例子


#include
using namespace std;
class A {
public:
A() { i = 1; }
void fun() {
cout << "fun in class A!" << endl;
}
public:
int i;
};
class B {
A a;
public:
B() { i = 2; }
A* operator->() {//重载箭头运算符的函数居然返回的是指针,也就是对象的地址
return &a;
}
void fun() {
cout << "fun in class B!" << endl;
}
private:
int i;
};
class C {
B b;
public:
C() { i = 3; }
B operator->() {//重载箭头运算符的函数返回的是对象
return b;
}
void fun() {
cout << "fun in class C!" << endl;
}
private:
int i;
};
int main()
{
C* p = new C(); //p是类C的一个指针
p->fun();
C c; //c是类C的对象
c->fun();
int i = c->i;
cout << i << endl;
system("pause");
return 0;
}C++中重载箭头运算符详解看见了吗?c是类C的一个对象,却可以使用箭头运算符。更神奇的是,你看一下运算结果,c->fun()居然结果是“fun in class A”,c->i的结果居然是1。


在C++ Primer中关于重载箭头运算符有这样一段总结:


(说明一)


对于形如point->mem的表达式来说,point必须是指向类对象的指针或者是重载了operator->的类的对象。根据point类型的不同,point->mem分别等价于


<1> (*point).mem                           //point是一个指针


<2>point.operator()->mem                //point是类的一个对象


而且,更为重要的是,按照我们一般的理解,重载箭头运算符返回的不应该是一个指针。那么你再看一下下面这段话:


(说明二)


重载箭头操作符必须返回指向类类型的指针,或者返回定义了自己的箭头操作符的类类型对象。


<1>如果返回类型是指针,则内置箭头操作符可用于该指针,编译器对该指针解引用并从结果对象获取指定成员。如果被指向的类型没有定义那个成员,则编译器产生一个错误。


<2>如果返回类型是类类型的其他对象(或是这种对象的引用),则将递归应用该操作符。编译器检查返回对象所属类型是否具有成员箭头,如果有,就应用那个操作符;否则,编译器产生一个错误。这个过程继续下去,直到返回一个指向带有指定成员的的对象的指针,或者返回某些其他值,在后一种情况下,代码出错。


那么现在给你解释一下程序的运行结果(非常重要)

<1>p是指针,按照上述说明一,应该调用的是(*p).fun(),这样结果就是“fun in class C!”


<2>c是定义了operator的类的一个对象,按照上述说明一,应该调用c.operator()->fun,接着类C的重载箭头运算符的成员函数返回值类型是类类型的其它对象,那么按照说明二,应该递归应用该操作符,那么现在来到了类B的重载箭头运算符的成员函数,此成员函数的返回值类型为指针,所以按照说明二,编译器对该指针解引用并从结果对象获取指定成员函数fun(),由于在类B的重载箭头运算符函数中返回的是类A的指针,所以调用类A的成员函数fun(),结果就是“fun in class A!”


     至于c->i,则是同理,自行感受。


最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台