【问题标题】:Constants and Classes Declarations Across Multiple Source Files in C++C++ 中跨多个源文件的常量和类声明
【发布时间】:2011-04-26 21:17:51
【问题描述】:

我确信这个问题被问了很多,但我似乎找不到任何相关的东西。我在 C++ 项目中有多个源文件。在典型的方式中,有多个带有类和函数声明的头文件以及关联的源文件及其定义。问题是,当我尝试使用在另一个文件中定义的一个类作为另一个文件中的类的成员时,即使使用 #include 指令,我也会遇到编译错误。解决这个问题的方法是先对类进行原型设计(这是正确的词吗?),然后再将其声明为成员。因此,如果 ClassA 在一个文件中,而 ClassB 在另一个文件中,并且我想在 ClassB 中使用 ClassA 成员,我必须写:


// ClassA.h
class ClassA {
    public: ClassA (void); };
// ClassB.h class ClassA; // prototype class ClassB { public: ClassA* ca; };

这正常吗?不管我使用指针还是实例,我仍然必须对它们进行原型设计。我发现如果结构和枚举位于单独的文件中,我还必须对其进行原型设计。我似乎无法在多个文件中使用使用#defineconst 声明的常量我收到未定义的错误,因此我不确定如何为它们提供更多文件范围。 typedefs 也是如此。我确信有一些我不记得的简单解决方法......感谢任何帮助!

【问题讨论】:

  • enum 的前向声明(您命名为“原型设计”的功能)仅在 C++0x 中允许并且仅在您同时声明基础类型时才允许。
  • 我以为enums 总是属于int?但无论哪种方式,当我转发声明时,声明底层类型的语法是什么?

标签: c++ scope declaration definition


【解决方案1】:

您要查找的词是“声明”,而不是“原型”。

无论如何,这是正常的。通常你只需要包含相关的头文件:

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

【讨论】:

  • 好的,我总是使用包含防护。那么我如何能够在多个文件中使用常量呢?我在标题的命名空间中定义了如下常量:const int CONSTANT = 0,我不能在其他文件中使用它们。我厌倦了使用static 限定符。这似乎是一个如此简单的问题,但我无法弄清楚。
【解决方案2】:

是的,这是显而易见的方式。

当您试图避免标头之间的相互依赖时,这种方法最合适。如果您确定两个标头之间不存在相互依赖关系,那么您 #include 一个又一个是正常的。

【讨论】:

    【解决方案3】:

    扩展康拉德的回答:

    是的,当您不必处理循环引用时,这很好。如果您确实必须担心循环继承、菱形问题或任何类似问题,这是我在别人的问题中找到的解决方案:

    // 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 的包含保护将为您解决问题。

    【讨论】:

      猜你喜欢
      • 2015-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多