fun();//错误。“A”类型没有重载成员“operator ->” system("pause"); return 0;}一般来说,类对象不能使_重载箭头运算符">
当前位置:   article > 正文

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

重载箭头运算符

首先看一个例子

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

看下面这个例子

  1. #include <iostream>
  2. using namespace std;
  3. class A {
  4. public:
  5. A() { i = 1; }
  6. void fun() {
  7. cout << "fun in class A!" << endl;
  8. }
  9. public:
  10. int i;
  11. };
  12. class B {
  13. A a;
  14. public:
  15. B() { i = 2; }
  16. A* operator->() { //重载箭头运算符的函数居然返回的是指针,也就是对象的地址
  17. return &a;
  18. }
  19. void fun() {
  20. cout << "fun in class B!" << endl;
  21. }
  22. private:
  23. int i;
  24. };
  25. class C {
  26. B b;
  27. public:
  28. C() { i = 3; }
  29. B operator->() { //重载箭头运算符的函数返回的是对象
  30. return b;
  31. }
  32. void fun() {
  33. cout << "fun in class C!" << endl;
  34. }
  35. private:
  36. int i;
  37. };
  38. int main()
  39. {
  40. C* p = new C(); //p是类C的一个指针
  41. p->fun();
  42. C c; //c是类C的对象
  43. c->fun();
  44. int i = c->i;
  45. cout << i << endl;
  46. system("pause");
  47. return 0;
  48. }


看见了吗?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,则是同理,自行感受。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/54700
推荐阅读
相关标签
  

闽ICP备14008679号