C++ 构建多个文件的困难解决方案

C++ 构建多个文件的困难解决方案,c++,building,C++,Building,我正在尝试构建一个包含三个文件的解决方案。对于main.cpp,它是四个文件 实体.h #pragma once #include "SystemBase.h" namespace Engine { class Entity { public: Entity() { } void s(SystemBase* sb) { } }; } #pragma once #include "SystemBase.h" #include "Entity.h" namespace

我正在尝试构建一个包含三个文件的解决方案。对于main.cpp,它是四个文件

实体.h

#pragma once

#include "SystemBase.h"

namespace Engine {

class Entity {
public:
    Entity() { }

    void s(SystemBase* sb) { }
};
}
#pragma once

#include "SystemBase.h"
#include "Entity.h"

namespace Engine {

class SubscribersList {
    friend SystemBase;

public:
    SubscribersList() { }

    void f(Entity* e) { }
};
}
 #pragma once

 #include "SubscribersList.h"
 #include "Entity.h"

 namespace Engine {

class SystemBase {
public:
    SystemBase() { }

    void g(Entity* e) { }

private:
    SubscribersList m;

};
}
订阅列表.h

#pragma once

#include "SystemBase.h"

namespace Engine {

class Entity {
public:
    Entity() { }

    void s(SystemBase* sb) { }
};
}
#pragma once

#include "SystemBase.h"
#include "Entity.h"

namespace Engine {

class SubscribersList {
    friend SystemBase;

public:
    SubscribersList() { }

    void f(Entity* e) { }
};
}
 #pragma once

 #include "SubscribersList.h"
 #include "Entity.h"

 namespace Engine {

class SystemBase {
public:
    SystemBase() { }

    void g(Entity* e) { }

private:
    SubscribersList m;

};
}
SystemBase.h

#pragma once

#include "SystemBase.h"

namespace Engine {

class Entity {
public:
    Entity() { }

    void s(SystemBase* sb) { }
};
}
#pragma once

#include "SystemBase.h"
#include "Entity.h"

namespace Engine {

class SubscribersList {
    friend SystemBase;

public:
    SubscribersList() { }

    void f(Entity* e) { }
};
}
 #pragma once

 #include "SubscribersList.h"
 #include "Entity.h"

 namespace Engine {

class SystemBase {
public:
    SystemBase() { }

    void g(Entity* e) { }

private:
    SubscribersList m;

};
}
不要关注标题中方法的主体。这只是为了让事情简单化。我找到了两种构建解决方案的方法。 1.在所有类名之前写class。但当我试图将实现与原型分离时,它崩溃了。 2.将所有代码写入一个文件中。
我不会/不会在所有类名之前编写关键字class来构建解决方案,当然我也不会/不会在一个文件中编写大型项目。那为什么我不能建造它呢?什么是魔法

要理解循环头依赖的问题,我们首先需要理解类声明和定义与不完整类型概念之间的区别

类型
类型
的原型或转发声明写为:

class Type;
class AnotherType;

class Type {
public:
    void aMemberFunc();
private:
    AnotherType *m_theOtherThing;
};
这样的转发声明允许您创建指向该类型的指针和引用。 但是,在声明
类型的完整类型之前,不能实例化、取消引用指向该类型的指针或使用对该类型的引用

class AnotherType {
    Type m_aType;
}
类型的声明可以写成:

class Type;
class AnotherType;

class Type {
public:
    void aMemberFunc();
private:
    AnotherType *m_theOtherThing;
};
现在我们可以创建声明实例,并且可以取消对
Type
的引用

但是,在取消引用或实例化另一个类型之前,必须完全声明另一个类型

class AnotherType {
    Type m_aType;
}
应该这样做,这为我们提供了另一种类型的完整声明和定义

这允许继续编写
Type::aMemberFunc
的定义:

void Type::aMemberFunc() {
    m_theOtherThing = new AnotherType();
}
如果我们没有按此顺序向编译器呈现此代码,而是提前呈现了
类型
另一类型
的完整声明:

class Type {
public:
    void aMemberFunc();
private:
    AnotherType *m_theOtherThing;
};

class AnotherType {
    Type m_aType;
}
然后
另一种类型*m_另一种类型将无法编译,因为该点未声明或正向声明另一个类型

切换顺序会得到:

class AnotherType {
    Type m_aType;
}

class Type {
public:
    void aMemberFunc();
private:
    AnotherType *m_theOtherThing;
};
现在
输入m_aType将不会编译,因为未声明
类型
。在这种情况下,转发声明不起作用

使用
#pragma一次
而不是标题保护,无论如何都不会改变问题
#pragma once
只确保头只包含一次,否则不会影响编译器处理代码的顺序。它当然不允许编译器在到达未定义的类型时忽略它们


对于这种类结构,编译器无法在不使用前向声明的情况下处理它。

这似乎是循环包含的问题。您可以改为向前声明一些类吗。您至少可以在SystemBase和SubscriberList中向前声明
实体
,因为它们只有一个指向类型
实体
可能重复的clcto的指针,它会工作一段时间,然后可能会导致歧义问题。而且。。。如果可能的话,我想找到一种方法来构建这段代码,而不需要过多的类关键字和forword声明。它是否应该防止循环头依赖?否
#pragma once
对这种情况没有帮助…谢谢大家。你记得我的基本知识。现在觉得自己很愚蠢。