C++ 代码组织
我有一个访问者模式实现:C++ 代码组织,c++,code-organization,visitor,C++,Code Organization,Visitor,我有一个访问者模式实现: 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 Ba
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) };
};
问题是A
和B
在访问者实现中的类型不完整。但我不想将实现放在单独的源文件中
有没有办法把它放在一个头文件中?要点是: 只要有两个类(例如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 { ... };
};
再一次,如果你有选择:不要这样做。更喜欢分割你的文件。这种解决方法,即使有很好的文档记录,也很难维护。执行前向声明
A
和B
。移动访问(A*A)代码>和访问(B*B)代码>在访客类别声明之外,并在A
和B
类别之后声明。为避免重复符号,请将其放入头文件,例如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(); }
“这是将其放在单个头文件中的一种方式吗?”为什么要将实现放在头文件中?如果将实现放在源文件中,则“类型不完整”不会有问题。请尝试转发声明。@AlexeyUsachov,但仍不允许在头文件中包含此类方法的实现。a
和b
类型不完整的问题提示问题在于方法调用,而不是a
和b
的用法。就我所见,最终需要将某个东西的实现移动到源文件,而没有纯头实现的解决方案。如果在多个源文件中包含这样一个文件,会发生什么?一旦你尝试将链接器链接到最终应用程序,难道你没有收到链接器错误吗?@AlgirdasPreidžius是的,谢谢你的评论,我已经对我的答案进行了改进,以避免链接器可能出现重复错误