You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Execute-Around Pointer代码为何仅一次解引用却触发两次operator->调用?

C++中operator->连续调用的原因解析

示例代码

#include <vector>
#include <iostream>

using std::vector;

class VisualizableVector {
  public:
    class proxy {
      public:
        proxy (vector<int> *v) : vect (v) {
          std::cout << "Before size is: " << vect->size () << '\n';
        }
        vector<int> * operator -> () {
          std::cout << "Operator ->* invoked on proxy\n";
          // std::cout << std::stacktrace::current() << '\n';
          return vect;
        }
        ~proxy () {
          std::cout << "After size is: " << vect->size () << '\n';
        }
      private:
        vector <int> * vect;
    };
    VisualizableVector (vector<int> *v) : vect(v) {}    
    proxy operator -> () {
       std::cout << "operator->() invoked on the VisualizableVector\n";
       return proxy (vect);
    }
  private:
    vector <int> * vect;
};

int main()
{
  vector<int> vec;
  VisualizableVector vecc(&vec);
  vecc->push_back(10);
}

运行结果

operator->() invoked on the VisualizableVector
Before size is: 0
Operator ->* invoked on proxy
After size is: 1

问题解答

这是C++标准对operator->的特殊规定:当你对一个对象使用->运算符时,编译器会持续调用该对象的operator->方法,直到返回的结果是一个原生指针(或是能直接通过->访问成员的类型,比如智能指针),之后才会用这个最终的指针去访问目标成员。

对应到代码逻辑:

  • 执行vecc->push_back(10)时,首先触发VisualizableVector类的operator->,返回一个proxy对象,同时输出第一行日志。
  • 编译器发现返回的proxy不是原生指针,于是继续调用proxy类的operator->,返回vector<int>*原生指针,同时输出第二行日志。
  • 拿到原生指针后,就用它调用push_back(10),修改向量的大小。
  • 最后proxy对象生命周期结束,调用其析构函数输出第三行日志。

你的猜测完全正确:->的调用逻辑就是反复调用operator->直到得到可直接访问成员的类型,这正是Execute-Around Pointer惯用法能实现的核心基础——通过中间proxy对象在目标操作前后插入额外逻辑。

内容的提问来源于stack exchange,提问作者einpoklum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 20:50:08