实现c ++访问者模式,避免循环依赖

Wil*_*yot 1 c++ circular-dependency

我在这里用C++实现了一个访问者模式.我有这个文件结构:

Base.h
---------------
#ifndef BASE_H
#define BASE_H

#include "visitor.h"

class Base{
public: virtual void accept(const visitor& v)=0;
};

#endif

Derived.h
-----------------
#ifndef DERIVED_H
#define DERIVED_H

#include "base.h"
#include "visitor.h"

class Derived : Base {
public: virtual void accept(const visitor& v);
};

#endif

visitor.h
------------------
#ifndef VISITOR_H
#define VISITOR_H

#include "base.h"
#include "derived.h"

class visitor {
    void visit(const base& base);
    void visit(const derived& derived);
};

#endif
Run Code Online (Sandbox Code Playgroud)

cpp文件只包含.h并定义上面链接中描述的acccept方法.我对这些文件结构的问题是标头之间的循环依赖.如果我用VS 2012编译它我得到这个错误:错误C2504:基类没有定义.谢谢你的建议,抱歉我的英语不好.

编辑:我已经更改了我的代码,如下所示:

Base.h
---------------
#ifndef BASE_H
#define BASE_H

//#include "visitor.h"
class visitor;

class Base{
public: virtual void accept(const visitor& v)=0;
};

#endif

Derived.h
-----------------
#ifndef DERIVED_H
#define DERIVED_H

#include "base.h"
//#include "visitor.h"

class visitor;

class Derived : Base {
public: virtual void accept(const visitor& v);
};

#endif

visitor.h
------------------
#ifndef VISITOR_H
#define VISITOR_H

//#include "base.h"
//#include "derived.h"

class base;
class derived;

class visitor {
    void visit(const base& base);
    void visit(const derived& derived);
};

#endif
Run Code Online (Sandbox Code Playgroud)

但是现在,在cpp实现上(在base.cpp和derived.cpp上)我得到了erorr c2872'visitor'ambiguos符号:

Base.cpp
---------
#include "base.h"
void base::accept(const visitor& v){ // on this line i get error c2872
   v.visit(this);
}

Derived.cpp
---------
#include "derived.h"
void derived::accept(const visitor& v){ // on this line i get error c2872
   v.visit(this);
}
Run Code Online (Sandbox Code Playgroud)

Som*_*ude 8

visitor.h头文件中,您不需要包含,编译器只需要知道basederived类存在.这可以通过用#include类的声明替换指令来轻松完成:

class base;
class derived;
Run Code Online (Sandbox Code Playgroud)

在其他两个头文件中,您不需要visitor.h包含,只需将其替换#include

class visitor;
Run Code Online (Sandbox Code Playgroud)

  • 这里的关键术语是"前瞻性宣言". (3认同)
  • @WileTheCoyot在*源文件*(`Base.cpp`和`Derived.cpp`)中,您需要包含`visitor.h`头文件。这是因为在头文件中,您只是告诉编译器“存在一个名为“visitor”的类,但在源文件中您实际上正在使用此类的实例,因此编译器需要完整的定义(而不仅仅是声明) )。 (2认同)