我确信这个问题很多,但我似乎无法找到任何相关内容。我在C ++项目中有多个源文件。在典型的方式中,有多个头文件具有类和函数声明以及相关的源文件及其定义。问题是,当我尝试使用另一个文件中定义的某个类作为不同文件中的类的成员时,即使使用#include
指令,也会出现编译错误。解决问题的原因是在将类声明为成员之前,先将类原型(是正确的词?)。因此,如果ClassA在一个文件中而ClassB在另一个文件中,并且我想在ClassB中使用ClassA成员,我必须写:
// ClassA.h
class ClassA {
public: ClassA (void); };
// ClassB.h
class ClassA; // prototype
class ClassB {
public: ClassA* ca; };
这是正常的吗?如果我使用指针或实例并不重要,我仍然必须对它们进行原型设计。我发现如果它们在单独的文件中,我也必须对结构和枚举进行原型化。我似乎无法使用#define
或const
在多个文件中声明的常量我得到的错误是未定义的,所以我不知道如何给它们提供更多的文件范围。 typedefs
也是如此。我确信有一些简单的解决方法,我不记得了......任何帮助都表示赞赏!
答案 0 :(得分:2)
你要找的词是“宣告”,而不是“原型”。
无论如何,这是正常的。通常你只需要包含相关的头文件:
// ClassB.h
#include "ClassA.h"
class ClassB {
public: ClassA* ca; };
这会导致循环引用出现问题(但在所有其他情况下都没问题)。
另一件事:不要忘记你的包含警卫,以防止多个包含文件。也就是说,始终按以下方式编写头文件:
#ifndef UNIQUE_IDENTIFIER_HERE
#define UNIQUE_IDENTIFIER_HERE
// Rest of header file here.
#endif // ndef UNIQUE_IDENTIFIER_HERE
UNIQUE_IDENTIFIER_HERE
通常是头文件名的全大写变体,例如‹PROJECTNAME›_‹PATH_TO_HEADER›_‹HEADERNAME›_H
。例如,我目前正在一个项目(称为“SeqAn”)中工作,该项目在路径parallel/taskdata.h
中有一个头文件。我使用的唯一标识符是SEQAN_PARALLEL_TASKDATA_H
。
答案 1 :(得分:0)
是的,这是显而易见的方式。
当您尝试避免标头之间的相互依赖时,此方法最适合。如果你确定两个标题之间没有相互依赖关系,那么你#include
就可以了。
答案 2 :(得分:0)
扩展康拉德的回答:
是的,当你不必处理循环引用时,这很好,很花哨。如果您做必须担心循环继承,钻石问题或任何类型的问题,这是我在其他人的问题中找到的解决方案:
// ClassA.h
class ClassB;
class ClassA {
public:
ClassB* cb;
};
// ClassA.cpp
#include "ClassA.h"
#include "ClassB.h"
// code
// ClassB.h
#include "ClassA.h"
class ClassB {
public:
ClassA* ca;
};
// ClassB.cpp
#include "ClassB.h"
// code
只要ClassA
仅尝试访问成员函数内ClassB
的成员,并且成员函数都在源文件中,您只需在标题中使用类声明,然后离开源文件的#include
,其中ClassA.h
包括后卫将为您解决问题。