如何在不定义结构的情况下在 C++ 中声明结构?

How can I declare a structure in C++ without defining it?

我一直在学习 cplusplus.com/doc/tutorial 上的教程。在函数页面的末尾,它讨论了函数原型设计。后来,我阅读了有关结构的内容。我觉得它看起来有点乱,我喜欢我的主要方法之后的代码块。所以我想知道我是否可以制作数据结构的原型。我试过这个:

#include <iostream>
using namespace std;

struct aStruct;

int main() {

    aStruct structure;

    structure.a = 1;
    structure.b = 2;

    cout << structure.a << ", " << structure.b << "\n";

    return 0;
}

struct aStruct {
    int a;
    int b;
};

可是我的IDE说的是"aStruct was not declared in this scope"。 那么,我如何制作一个数据结构的原型,以便它的大部分可以位于 main 方法下面?

教程页面: Functions Data strucutres

通常,pre-declaring 结构的唯一原因是为了避免在定义结构时出现循环引用。正确的解决方案是使用 header,并将结构定义隐藏在 header 中:

里面 aStruct.h:

#ifndef _ASTRUCT_H
#define _ASTRUCT_H

struct aStruct {
  int a;
  int b;
};

#endif /* _ASTRUCT_H */

#ifdefs/etc 是为了防止意外 multiple-inclusion,否则会导致错误) 里面 main.cpp:

#include <iostream>
#include "aStruct.h"
using namespace std;

int main() {

    aStruct structure;

    structure.a = 1;
    structure.b = 2;

    cout << structure.a << ", " << structure.b << "\n";

    return 0;
}

在漫长的 运行 中,通过将代码正确地组织到单独的文件中,您会更快乐。

我将把它留作 reader 的练习,以通过使用 #ifdef ASTRUCT_H/#define ASTRUCT_H/#endif lines.

正确防止 header 的多重包含

How can I declare a structure in C++ without defining it?

与您在代码中所做的完全一样。

But my IDE said that "aStruct was not declared in this scope"

好吧,这是一个非常令人困惑的诊断。 gcc 说 "error: aggregate 'aStruct structure' has incomplete type and cannot be defined"。您不能定义不完整类型的 object。

So, how would I prototype a data structure so the bulk of it can be below the main method?

你不能。如果这 4 行太多,请将定义放入 header。如果有的话,您可以在 main 之后甚至在另一个编译单元中保留成员函数的实现。就像您可以使用免费功能一样。

将结构定义放在 int main() 之上

你可以像

这样使用前向声明

aStruct *结构;

 1 #include <iostream>
  2 using namespace std;
  3 
  4 class aStruct;
  5 
  6 int main() {
  7 
  8     aStruct *structure ;
  9 /*
 10     structure->a = 1;
 11     structure->b = 2;
 12 
 13     cout << structure->a << ", " << structure->b << "\n";
 14 */
 15     return 0;
 16 }
 17 
 18 struct aStruct {
 19     int a;
 20     int b;
 21 };

aStruct 是一个不完整的类型,所以编译器不知道 ab 是什么。

这种前向声明类型的技巧只能在需要将类型指定为 class 成员或函数参数时使用。但是,它仅适用于指向转发的不完整类型的指针。原因是,没有定义,编译器不知道类型的大小,但指针总是具有相同的大小。

所以,这是一个例子。

aStruct.h

struct aStruct
{
   int a;
   int b;
};

header.h

struct aStruct;

void func(aStruct* ptr);

source.cpp

#include "header.h" // at this point the compiler only knows of a type aStruct
#include "aStruct.h" // now the compiler has the definition of aStruct

void func(aStruct* ptr)
{
  ptr->a = 42;
}

关于

I wondered if I could prototype a data structure. I tried this:

#include <iostream>
using namespace std;

struct aStruct;

int main() {

    aStruct structure;

    structure.a = 1;
    structure.b = 2;

不,无法对结构进行“原型设计”,因此无法在定义结构之前使用其成员。

您可以将结构定义放在main内或main之前,但无论如何它必须在使用成员的代码之前。


如果您不想在编辑器中看到它,那么您可以

  • 使用可以折叠代码区域的编辑器,and/or

  • 将定义放在头文件中。


C 和 C++ 专为几乎单遍编译而设计,其中通常使用的每个名称都必须已经声明。这包括结构的字段。据我所知,此规则的唯一例外是跳转标签,因为如果没有例外,它们将需要某种向前声明标签的方式(更复杂)或必须不支持向前跳转(不受欢迎的限制)。

您可以像在上面的代码中一样前向声明一个结构,但是您会发现一个限制:尽管结构名称本身是已知的并且可以使用(以有限的方式) ,如果没有更完整的定义,您实际上无能为力。完整性的下一个级别是有一个 class 定义 ,它指定结构的成员,因此它的大小。它足够完整,可以允许对结构的所有使用,但是要使代码 link 您还需要所有成员函数的定义,如果这些成员函数已经声明但未在 class 定义中内联定义 - 而这是第三个完整性级别,一个完全完整的定义。

关于标准术语,前向声明的结构称为 不完整类型 ,并且具有已知其大小的定义的结构是 完整类型。完全完整的结构体定义,没有特殊名称,所有成员函数定义。