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
相关产品推荐
相关产品推荐

