C++11变种访问者模式代码输出V而非A的问题排查请求
问题分析:访问者模式输出不符合预期
你的代码问题出在子类没有重写Accept方法,导致调用的是基类Visitable的Accept实现。
在基类Visitable的Accept中,*this的静态类型是Visitable,所以编译器会匹配Visitor类中参数为const Visitable&的visit重载,最终输出"V"。而访问者模式的核心就是让子类通过重写Accept,把自身的实际类型暴露给访问者。
修复方案
修复后的完整代码如下:
#include <iostream> using namespace std; class A; class B; class Visitable; class Visitor { public: void visit(const A& a) { std::cout << "A" << std::endl; } void visit(const Visitable& v) { std::cout << "V" << std::endl; } void visit(const B& b) { std::cout << "B" << std::endl; } }; class Visitable { public: virtual void Accept(Visitor* visitor) = 0; // 改为纯虚函数,强制子类实现 }; class A : public Visitable { public: void Accept(Visitor* visitor) override // C++11用override明确重写 { visitor->visit(*this); // 此处*this静态类型为A,匹配对应visit重载 } }; class B : public Visitable { public: void Accept(Visitor* visitor) override { visitor->visit(*this); } }; int main() { Visitor* v = new Visitor(); A* a = new A(); a->Accept(v); // 现在会输出"A" // 释放内存避免泄漏 delete v; delete a; return 0; }
关键说明
- 将基类
Visitable的Accept设为纯虚函数,强制所有子类必须实现自己的Accept版本,避免遗漏导致的问题。 - 子类
A和B重写Accept后,*this的静态类型变为子类本身,编译器会正确匹配Visitor中对应子类的visit重载。 - C++11的
override关键字可以让编译器校验是否正确重写了基类虚函数,减少拼写错误等低级问题。
内容的提问来源于stack exchange,提问作者jsubi
相关产品推荐
相关产品推荐

