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

时间:2015-03-16 22:00:32

标签: c++ data-structures

我一直关注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说&#34; aStruct未在此范围内声明&#34;。 那么,我如何对数据结构进行原型设计,以便大部分数据结构可以低于主要方法?

教程页面: Functions Data strucutres

6 个答案:

答案 0 :(得分:3)

通常,预先声明结构的唯一原因是为了避免定义结构中的循环引用。正确的解决方案是使用标题,并在标题中隐藏结构定义:

内部aStruct.h

struct aStruct {
  int a;
  int b;
};

内部main.cpp

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

struct aStruct;

int main() {

    aStruct structure;

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

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

    return 0;
}

从长远来看,通过将代码正确地组织到单独的文件中,您会更高兴。

我会将其作为练习留给读者使用#ifdef ASTRUCT_H/#define ASTRUCT_H/#endif lines来正确防止多次包含标题。

答案 1 :(得分:1)

  

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

按照您在代码中的确切方式。

  

但我的IDE说&#34; aStruct未在此范围内声明&#34;

嗯,这是一个非常令人困惑的诊断。 gcc说&#34;错误:聚合&#39; aStruct结构&#39;具有不完整的类型,无法定义&#34;。您无法定义不完整类型的对象。

  

那么,我如何对数据结构进行原型设计,以便它的大部分可以在主方法之下呢?

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

答案 2 :(得分:1)

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

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

所以,这是一个例子。

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;
}

答案 3 :(得分:0)

您可以使用

等前向声明

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 };

答案 4 :(得分:0)

关于

  

我想知道我是否可以对数据结构进行原型设计。我试过这个:

#include <iostream>
using namespace std;

struct aStruct;

int main() {

    aStruct structure;

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

不,没有办法“原型化”结构,因此可以在定义结构之前使用它的成员。

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


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

  • 使用可折叠代码区域的编辑器和/或

  • 将定义放在头文件中。


C和C ++是为几乎单通道编译而设计的,通常每个名称都必须已经声明。这包括结构的领域。据我所知,这个规则的唯一例外是跳转标签,因为没有例外,他们需要一些前向声明标签的方式(更复杂)或者必须不支持前向跳跃(不受欢迎的限制)。 / p>

您可以像上面的代码一样转发声明一个结构,但是你有你发现的限制:虽然结构名称本身是已知的并且可以使用(以有限的方式)如果没有更完整的定义,你可以用它做的事情真的不多。完整性的下一级是有一个类定义,它指定结构的成员,因此它的大小。它足够完整以允许所有结构的使用,但是为了使代码链接你还需要所有成员函数的定义,如果已经声明但未在类定义中内联定义 - 这是第三级完整性,一个完整的定义。

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

答案 5 :(得分:-2)

将结构定义放在int main()

之上