Sco*_*ott 1 c++ inheritance forward-declaration
在处理包括彼此在内的多个类时,我遇到了这个错误:
error: expected class-name before '{' token
Run Code Online (Sandbox Code Playgroud)
我看到发生了什么,但我不知道如何正确纠正它.这是代码的抽象版本:
啊
#ifndef A_H_
#define A_H_
#include "K.h"
class A
{
public:
A();
};
#endif /*A_H_*/
Run Code Online (Sandbox Code Playgroud)
A.cpp
#include "A.h"
A::A() {}
Run Code Online (Sandbox Code Playgroud)
BH
#ifndef B_H_
#define B_H_
#include "A.h"
class B : public A
{ // error: expected class-name before '{' token
public:
B();
};
#endif /*B_H_*/
Run Code Online (Sandbox Code Playgroud)
B.cpp
#include "B.h"
B::B() : A() {}
Run Code Online (Sandbox Code Playgroud)
JH
#ifndef J_H_
#define J_H_
#include "B.h"
class J
{
public:
J();
};
#endif /*J_H_*/
Run Code Online (Sandbox Code Playgroud)
J.cpp
#include "J.h"
J::J() {}
Run Code Online (Sandbox Code Playgroud)
KH
#ifndef K_H_
#define K_H_
#include "J.h"
class K : public J
{ // error: expected class-name before '{' token
public:
K();
};
#endif /*K_H_*/
Run Code Online (Sandbox Code Playgroud)
K.cpp
#include "K.h"
K::K() : J() {}
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include "A.h"
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
从main.cpp开始,我可以确定这是编译器看到的:
#include "A.h"
#ifndef A_H_
#define A_H_
#include "K.h"
#ifndef K_H_
#define K_H_
#include "J.h"
#ifndef J_H_
#define J_H_
#include "B.h"
#ifndef B_H_
#define B_H_
#include "A.h"
class B : public A
{ // error: expected class-name before '{' token
Run Code Online (Sandbox Code Playgroud)
所以,当我们到达B时,A的定义并不完整.我被告知有时你需要使用前向声明,然后将#include语句移动到.cpp文件中,但我没有运气.如果我尝试这样的话,我只会得到额外的错误:
error: forward declaration of 'struct ClassName'
Run Code Online (Sandbox Code Playgroud)
我想也许我只是不在正确的地方做事.有人可以告诉我如何编译这段代码吗?非常感谢你!
编辑:我想指出这只是真实代码的抽象版本.我认识到,没有引用ķ在一个或乙在Ĵ,但在真正的代码,我觉得他们是完全必要的.也许如果我简要介绍一下真正的类,有人可以帮我重组或修改我的代码.
类阿是一个抽象类节点充当用于在图中的节点的接口.B类是A的许多不同实现之一.同样,J类是一个抽象的Visitor类,K是相应的实现.这是具有更多上下文的代码:
啊(抽象节点)
#ifndef A_H_
#define A_H_
#include "K.h"
class K;
class A
{
public:
A();
virtual void accept(const K&) const = 0;
};
#endif /*A_H_*/
Run Code Online (Sandbox Code Playgroud)
A.cpp
#include "A.h"
A::A() {}
Run Code Online (Sandbox Code Playgroud)
Bh(具体节点)
#ifndef B_H_
#define B_H_
#include "A.h"
class K;
class B : public A
{ // error: expected class-name before '{' token
public:
B();
virtual void accept(const K&) const;
};
#endif /*B_H_*/
Run Code Online (Sandbox Code Playgroud)
B.cpp
#include "B.h"
B::B() : A() {}
void B::accept(const K& k) const { k.visit(this); }
Run Code Online (Sandbox Code Playgroud)
Jh(抽象访客)
#ifndef J_H_
#define J_H_
#include "B.h"
class B;
class J
{
public:
J();
virtual void visit(const B*) const = 0;
};
#endif /*J_H_*/
Run Code Online (Sandbox Code Playgroud)
J.cpp
#include "J.h"
J::J() {}
Run Code Online (Sandbox Code Playgroud)
Kh(具体访客)
#ifndef K_H_
#define K_H_
#include "J.h"
class B;
class K : public J
{ // error: expected class-name before '{' token
public:
K();
virtual void visit(const B*) const;
};
#endif /*K_H_*/
Run Code Online (Sandbox Code Playgroud)
K.cpp
#include "K.h"
K::K() : J() {}
void K::visit(const B*) const {};
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include "A.h"
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不得不添加一些前向声明来使一些额外的错误(当我添加细节时)消失.其中一些可能没有必要或正确.
您的标题包含是圆形的.A - > K - > J - > B - > A.使用前向声明是避免这种复杂性的最简单方法,但只有当声明的类仅使用对包含的类的引用或指针时才有可能.例如,您不能在Kh或Bh中使用前向声明,因为它们分别从J和A继承.但是,根据您实际使用的方式,您可能可以替换#include "K.h"
Ah 中的.class K;
K
A
谈论混乱.