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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 21:39:36