Шаблон посетителя в C ++ в среде только заголовка - PullRequest
3 голосов
/ 04 ноября 2019

В настоящее время у меня проблемы с реализацией Visitor-Pattern в библиотеке только для заголовков в C ++.

Рассмотрим следующий класс, который должен поддерживать посещение посетителем (для простоты интерфейса нет)причины):

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

Вот интерфейс для посетителей:

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

В библиотеке только для заголовков Acceptor.hpp должен включать Visitor.hpp, а Visitor.hpp должен включатьAcceptor.hpp. Поскольку оба заголовка защищены Include-Guards , последний не удастся. Использование предварительных объявлений также не решит проблему.

1 Ответ

4 голосов
/ 04 ноября 2019

Для Visitor достаточно неполного типа Acceptor (он же class Acceptor;). Следовательно, вы можете разбить циклические #include с, включив Visitor в 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 потому что все функции-члены кода OPs 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
...