문제

서로를 포함한 여러 수업을 다룰 때이 오류가 발생합니다.

error: expected class-name before '{' token

무슨 일이 일어나고 있는지 알지만 올바르게 수정하는 방법을 모르겠습니다. 다음은 코드의 초록 버전입니다.

#ifndef A_H_
#define A_H_

#include "K.h"

class A
{
    public:
        A();

};

#endif /*A_H_*/

A.CPP

#include "A.h"

A::A() {}

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_*/

B.CPP

#include "B.h"

B::B() : A() {}

JH

#ifndef J_H_
#define J_H_

#include "B.h"

class J
{
    public:
        J();
};

#endif /*J_H_*/

J.CPP

#include "J.h"

J::J() {}

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_*/

K.CPP

#include "K.h"

K::K() : J() {}

main.cpp

#include "A.h"

int main()
{
    return 0;
}

시작 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

그래서, 우리가 도착하면의 정의가 완료되지 않습니다. . 나는 때때로 당신이 선언문을 사용하고 움직여야한다고 들었습니다. #포함 진술 .cpp 파일이지만 운이 좋지 않습니다. 그런 것을 시도하면 추가 오류가 발생합니다.

error: forward declaration of 'struct ClassName'

어쩌면 나는 단지 올바른 장소에서 일을하지 않는다고 생각합니다. 누군가이 코드를 컴파일하는 방법을 보여줄 수 있습니까? 매우 감사합니다!


편집 : 이것은 단지 실제 코드의 추상화 된 버전이라고 지적하고 싶습니다. 나는 언급이 없다는 것을 알고있다 케이 안에 또는 안에 제이, 그러나 실제 코드에는 실제 코드가 있으며 완전히 필요하다고 생각합니다. 아마도 실제 클래스에 대한 간단한 설명을한다면 누군가가 내 코드를 재구성하거나 수정하는 데 도움이 될 수 있습니다.

수업 그래프의 노드에 대한 인터페이스 역할을하는 추상 노드 클래스입니다. 수업 여러 가지 다른 구현 중 하나입니다. . 같은 방식으로 클래스 제이 추상 방문자 수업입니다 케이 해당 구현입니다. 다음은 조금 더 문맥이있는 코드입니다.

(추상 노드)

#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_*/

A.CPP

#include "A.h"

A::A() {}

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_*/

B.CPP

#include "B.h"

B::B() : A() {}

void B::accept(const K& k) const { k.visit(this); }

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_*/

J.CPP

#include "J.h"

J::J() {}

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_*/

K.CPP

#include "K.h"

K::K() : J() {}

void K::visit(const B*) const {};

main.cpp

#include "A.h"

int main()
{
    return 0;
}

(세부 사항을 추가했을 때)가 사라지는 추가 오류를 만들기 위해 선언문을 추가해야했습니다. 그들 중 일부는 필요하거나 정확하지 않을 수 있습니다.

도움이 되었습니까?

해결책

원형 포함은 작동하지 않습니다.

내포물을 엄격한 최소로 유지하십시오. 그렇게한다면, 당신은 모두 괜찮을 것이거나 디자인에서 문제를 발견하게 될 것입니다. 귀하의 경우, 나는 당신의 디자인에 아무런 문제가 없습니다.

클래스 k를 정의 할 때 B는 B 형의 객체에 대한 포인터 만 사용하고 있습니다. B를 정의 할 필요는 없습니다 ( "헤더 파일 포함"에서와 같이). 따라서 귀하의 경우, "BH"에 포함 된 "BH"에 대한 포함을 "클래스 B"로 대체했습니다. 충분하다. (클래스 j도 마찬가지)

다른 팁

헤더 포함은 원형입니다. A -> k-> j-> b-> A. 전방 선언을 사용하는 것은 그러한 복잡성을 피하는 가장 간단한 방법이지만, 선언 된 클래스가 참조 또는 포인터 만 포함되는 클래스에만 사용하는 경우에만 가능합니다. 예를 들어 J 및 A에서 각각 상속하기 때문에 KH 또는 BH에서 전방 선언을 사용할 수 없습니다. 그러나 교체 할 수 있습니다 #include "K.h" 아와 함께 class K; 실제로 사용하는 방식에 따라 다릅니다 K 안에 A.

혼란에 대해 이야기하십시오.

이 구체적인 예에서는 제거하십시오

#include "B.h"

파일에서 J.h 거기에는 필요하지 않기 때문입니다. 그것이 작동하지 않으면 방법에 대한 자세한 내용이 필요합니다. J 용도 B...

편집하다

부터 J 포인터 만 사용합니다 B, 조언은 동일하게 유지됩니다 :-) :

제거하다 #include "B.h" ~에서 J.h 그리고이를 선언으로 바꾸십시오 B:

(J.h)
class B;

class J
{
  // ...
  virtual void visit(const B*) const = 0; // This will work with forward declaration
}

또한 제거하십시오 #include "K.h"~에서 A.h.

중요한

물론 각 CPP 파일에 필요한 포함을 추가해야합니다.

(J.cpp)
#include "B.h"
// ...
// Go ahead with implementation of J
// ...

(동일 A.cpp, 포함 K.h)

주요 문제는 헤더 파일에 원형 방식으로 서로를 포함한다는 것입니다. A는 B를 포함하는 k를 포함하여 B를 포함합니다. 여기에는 A가 포함됩니다. 디자인 드로잉 보드로 돌아가서 종속성 중 일부를 자르 거나이 원형 의존성이 발생하지 않도록 클래스를 완전히 재구성해야합니다.

문제는 헤더 파일이 서로 주기적으로 의존한다는 것입니다. 포함하지 마십시오 K.h 안에 A.h 그리고 B.h 안에 J.h. 그들은 거기에서 필요하지 않습니다.

편집과 관련하여 : 이것은 객체가 상호 작용하는 가장 좋은 방법이 아닙니다. 디자인을 다시 생각하십시오. 누가 전화 node.accept(visitor)? 전화 할 수 없습니다 visitor(node) 곧장?

또한 그래프 라이브러리를 설계하려는 경우 boost.graph 도서관.

즉, 포인터 만 사용하기 때문에 B 안에 J.h, 당신은 포함 할 필요가 없습니다 B.h, 수업을 전진합니다.

class B;

struct J
{
    virtual void visit(const B*) const = 0;
};

그런 다음 포함하십시오 B.h 당신의 K.cpp 파일.

#include "K.h"
#include "B.h"

void K::visit(const B* b) const
{
    // use b here any way you want
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top