3

我目前在 C++ 的仅标头库中实现访问者模式时遇到了麻烦。

考虑以下应该支持访问者访问的类(为简单起见没有接口):

class Acceptor
{
    void accept(Visitor* v)
    {
        v->visit(this);
    }
};

这是访问者的界面:

class Visitor
{
    virtual void visit(Acceptor* t) = 0;
};

在 Header-Only 库中,Acceptor.hpp 必须包含 Visitor.hpp,Visitor.hpp 必须包含 Acceptor.hpp。由于两个标头都受Include-Guards保护,因此后一个标头将失败。使用前向声明也不能解决问题。

4

1 回答 1

4

对于Visitor不完整类型的Acceptor(aka class Acceptor;) 就足够了。#include因此,您可以通过包含Visitorin来打破循环s,Acceptor反之亦然。

为了证明这一点,我制作了一个单一文件MCVE

class Acceptor;

class Visitor
{
    friend class Acceptor;

    virtual void visit(Acceptor* t) = 0;
};

class Acceptor
{
    void accept(Visitor* v)
    {
        v->visit(this);
    }
};

coliru 现场演示

笔记:

我必须添加 ,friend class Acceptor因为 OP 代码的所有成员函数都是private. 然而,即使这样,不完整的类型class Acceptor似乎也足够了。


使用单独的文件:

文件visitor.h

#ifndef VISITOR_H
#define VISITOR_H

class Acceptor;

class Visitor
{
    friend class Acceptor;

    virtual void visit(Acceptor* t) = 0;
};

#endif // VISITOR_H

文件acceptor.h

#ifndef ACCEPTOR_H
#define ACCEPTOR_H

#include "visitor.h"

class Acceptor
{
    void accept(Visitor* v)
    {
        v->visit(this);
    }
};

#endif // ACCEPTOR_H
于 2019-11-04T15:09:57.633 回答