【问题标题】:Forward declaration of struct结构的前向声明
【发布时间】:2012-06-09 07:45:08
【问题描述】:

我有一个头文件 a.h,在里面我声明了一个结构。该结构的名称是file。在file 里面我有 3 个成员:a、b、c。在 a.cpp 中,我实现了该结构并为该结构变量分配了一些值。

现在我有另一个文件 b.h。在里面我有一个结构file的前向声明。直到此时,如果我编译它并没有显示错误,但是当我要通过该 b.cpp 类访问该结构中存在的变量时,它会给出类似“未定义结构”的错误。

我做错了什么?

【问题讨论】:

  • 请改写问题,在句末使用大写字母,否则难以阅读。

标签: c++


【解决方案1】:

要访问成员,需要完整的定义。您需要 include b.cpp 内的标头,而不仅仅是前向声明 struct(这会产生不完整的类型)。

编辑:

一个前向声明就足够了:

class B;
class C
{
    B& b;
    B* b;
    B foo();
    foo(B b);
};

但不是为了

class B;
class C
{
    B b;   //ERROR
    B foo()
    {
        B x; //error
        x.whatever(); //error
        return B(); //error
    }
};

【讨论】:

  • 那么类的前向声明呢?在这种情况下编译器如何知道内存布局
  • @vivek 它不需要。如果你只有引用或指针,或者使用类作为返回类型或作为参数传递,它不需要知道完整的定义。
  • 感谢兄弟的回复 .. 所以你说编译器只有在你想要结构的前向声明时才会搜索完整的定义。对于课程,它会自动知道??
  • @vivek 不,它与类或结构无关。
  • 但是不包括头文件我们可以去类的前向声明并使用它的成员?这是我得到怀疑的地方。我正在使用结构,就像我对类的前向声明一样
【解决方案2】:

您需要包含使用成员的结构的定义,否则编译器不知道它们是什么。

所以如果你有 b.cpp,这个

   func(mystruct &s)
   {
        s.a = 1;
   }

编译器在执行分配之前是正常的。此时,它试图在 'mystruct' 中找到 'a' 的定义,但找不到。

您应该在 b.cpp 中 #include "a.h",或者可能,根据 a.h 中的其他内容,您可能需要一个单独的结构标题并将其包含在内。

【讨论】:

  • 那么类的前向声明呢?这里我们不必包含相应类的头文件??
  • 我没有说alter b.h,我说的是alter b.cpp。您可以使用前向声明,编译器不需要知道任何有关结构内容的信息,但是当您访问内容时,它显然确实需要这些信息。
【解决方案3】:

错误的根本原因是什么?

当您转发声明一个类型时,编译器会将其视为不完整类型

前向声明告诉编译器所述类型存在,而没有更多关于特定类型的信息。因此,您不能对其执行任何操作(如创建对象或取消引用指向该类型的指针)需要编译器知道其内存布局的类型。

解决方案:

如果你需要延迟结构成员,你不能转发声明,你需要在源文件中包含头文件。这将确保编译器知道类型的内存布局。您必须相应地设计您的项目。

【讨论】:

  • 可能值得一提的是,不完整的类型有时用于封装 API。它们有效地强制用户仅通过公开的 API 函数访问结构。因此,另一种方法可能是让他添加所需的 API 函数,而不是直接访问成员。
  • @AmbrozBizjak:说得好。确实如此。但这取决于意图目的以及最后的设计 i>.我们不知道他们中的任何一个,因为 OP 选择抽象名称,如 AB 等等..
  • 那么类的前向声明呢?在这种情况下,编译器如何知道内存布局?
  • @vivek:它没有,直到它看到类定义。如果您尝试在前向声明和定义之间使用类,那只会对编译器造成问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
  • 2017-04-05
  • 2016-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多