fun();//错误。“A”类型没有重载成员“operator ->” system("pause"); return 0;}一般来说,类对象不能使_重载箭头运算符">
赞
踩
首先看一个例子
- #include <iostream>
- using namespace std;
- class A
- {
- void fun()
- {
- cout << "amazing" << endl;
- }
- };
- int main()
- {
- A a;
- a->fun();//错误。“A”类型没有重载成员“operator ->”
- system("pause");
- return 0;
- }

一般来说,类对象不能使用箭头运算符访问成员函数,而应该使用点运算符。但是,如果该类重载了箭头运算符,则情况发生改变。
看下面这个例子
- #include <iostream>
- 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++ 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,则是同理,自行感受。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。