C++ 中多个源文件的常量和类声明
我确信这个问题被问了很多,但我似乎找不到任何相关的内容。我的 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
也是如此。我确信有一些我不记得的简单解决方案......任何帮助都会受到赞赏!
I am sure this problem is asked a lot but I can't seem to find anything relevant. I have multiple source files in a C++ project. In typical fashion, there are multiple header files with class and function declarations and associated source files with their definitions. The problem is that when I try to use one of my classes defined in another file as a member for a class in a different file, I get compile errors even when uses the #include
directive. What fixes the problem is by prototyping (is that the right word?) the class first before declaring it a member. So if ClassA is in one file and ClassB is in another and I want to use a ClassA member in ClassB I must write:
// ClassA.h
class ClassA {
public: ClassA (void); };
// ClassB.h
class ClassA; // prototype
class ClassB {
public: ClassA* ca; };
Is this normal? It doesn't matter if I use pointers or instances, I still must prototype them. I have found that I also must prototype structs and enums if they are in separate files. I can't seem to use constants declared using #define
, or const
across multiple files I get errors that they are undefined so I am not sure how to give them more than file scope. The same goes for typedefs
. I am sure there is some easy fix to this that I am not remembering... any help is appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您要查找的词是“声明”,而不是“原型”。
无论如何,这都是正常的。通常您只需包含相关的头文件:
但这会导致循环引用出现问题(但在所有其他情况下都没有问题)。
另一件事:不要忘记你的包含防护,以防止文件的多次包含。也就是说,始终按以下方式编写头文件:
UNIQUE_IDENTIFIER_HERE
通常是头文件名的全大写变体,例如>_>_>_H
。例如,我目前正在处理一个项目(称为“SeqAn”),该项目在路径parallel/taskdata.h
中有一个头文件。因此,我使用的唯一标识符是SEQAN_PARALLEL_TASKDATA_H
。The word you’re looking for is “declare”, not “prototype”.
In any case, that’s normal. Usually you’d just include the relevant header files:
This will cause problems with circular references, though (but in all other cases it’s fine).
Another thing: Don’t forget your include guards, to protect against multiple inclusion of a file. That is, always write header files in the following way:
The
UNIQUE_IDENTIFIER_HERE
is usually an all-uppercase variant of the header file name, e.g.‹PROJECTNAME›_‹PATH_TO_HEADER›_‹HEADERNAME›_H
. For example, I’m currently working in a project (called “SeqAn”) that has a header file in the pathparallel/taskdata.h
. The unique identifier I use is thusSEQAN_PARALLEL_TASKDATA_H
.是的,这是显而易见的方式。
当您试图避免标头之间的相互依赖时,此方法最合适。如果您确定两个标头之间不会出现相互依赖关系,那么您在另一个标头中
#include
是正常的。Yes it is obvious way.
This approach is most suitable when you're trying to avoid mutual dependencies among headers. If you're sure that no mutual dependency appears between two headers it is normal that you
#include
one in another.扩展康拉德的答案:
是的,当您不必处理循环引用时,这很好。如果您确实必须担心循环继承、钻石问题或任何类似的问题,这是我在其他人的问题中找到的解决方案:
只要
ClassA
只尝试要在成员函数中访问ClassB
的成员,并且成员函数都在源文件中,您可以只在头文件中使用类声明,并保留#include
对于源文件,其中ClassA.h
的包含防护将为您解决问题。To expand on Konrad's answer:
Yes, that's fine and dandy when you don't have to deal with circular references. If you do have to worry about circular inheritance, the diamond problem, or anything of the sort, here's a solution I found in someone else's question:
As long as
ClassA
only tries to access members ofClassB
inside member functions, and the member functions are all in the source file, you can just use a class declaration in the header, and leave the#include
for the source file, whereClassA.h
's include guard will solve the problem for you.