代码整理

Code organizing

我有这个访客模式实现:

class Visitor {
  public:
    Visitor() {}
    void visit(A *a){ a->doSomething(); }
    void visit(B *b){ b->doSomething(); }
};

class Base {
  public:
    Base() {}
    virtual void accept(Visitor *v) = 0;
};

class A: public Base {
  public:
    A():Base() {}
    void accept(Visitor *v) override { v->visit(this) };
    .....
};

class B: public Base {
  public:
    B():Base() {}
    void accept(Visitor *v) override { v->visit(this) };
};

问题是 AB 在访问者实现中的类型不完整。但我不想将实现放在单独的源文件中。

有没有办法把它放在一个单独的头文件中?

要点是:

只要你有两个类(例如A和Visitor),并且每个的实现都需要另一个的声明,你就不能合并实现和声明。

你的情况:

class Visitor {
public:
    // Visitor's implementation needs A's declaration
    void visit(A *a){ a->doSomething(); }
};

class A {
  public:
    // A's implementation needs Visitor's declaration
    void accept(Visitor *v) { v->visit(this) };
    void doSomething() { ... };
};

这就是您希望在单独的文件中进行声明和实现的原因之一。 还有很多其他原因,包括不同的编译时间。

请问为什么要在同一个文件中实现所有这些?

但是:

根据您想要实现的目标,您可能想要欺骗它。但这将是一个痛苦的维持。 除非有非常好的和不寻常的理由,否则我永远不会那样做

例如,我假设类似的东西应该有效:

class Doer {
  public:
    // Doer's implementation don't needs Visitor's declaration
    virtual void doSomething()=0;
};

class A;
class Visitor {
public:
    // Visitor's implementation needs Doer's declaration
    void visit(A *a){ ((Doer*)a)->doSomething(); }
};

class A: public Doer {
  public:
    // A's implementation needs Visitor's declaration
    void accept(Visitor *v) { v->visit(this) };
    void doSomething() override { ... };
};

再说一次,如果你有选择:不要那样做。更喜欢拆分文件。这种解决方法,即使有详细记录,也很难维护。

做前向声明 AB。将您的 visit(A*a);visit(B*b); 移到访客的 class 声明之外,并在 AB class 之后声明。为避免重复符号将其放入头文件,例如 Header.h:

//forward declarations
class A;
class B;

class Visitor {
public:
    Visitor() {}
    void visit(A *a);
    void visit(B *b);
};

class Base {
public:
    Base() {}
    virtual void accept(Visitor *v) = 0;
};

class A: public Base {
public:
    A():Base() {}
    void accept(Visitor *v) override { v->visit(this); };
    void doSomething(){};
};

class B: public Base {
public:
    B():Base() {}
    void accept(Visitor *v) override { v->visit(this); };
    void doSomething(){};
};

这个声明应该放在cpp文件中,以避免重复的符号,例如将它添加到main.cpp:

#include "Header.h"

//outside declarations of methods
void Visitor::visit(A *a){ a->doSomething(); }
void Visitor::visit(B *b){ b->doSomething(); }