为什么我不能多声明一个类

时间:2010-02-04 08:45:49

标签: c++

我可以这样做

extern int i;
extern int i;

但是我不能用类

做同样的事情
class A {
..
}
class A {
..
}

虽然在这两种情况下都没有分配内存。

9 个答案:

答案 0 :(得分:24)

以下是声明

extern int i;
class A;

接下来的两个是定义

int i;
class A { ... }

规则是:

  • 定义也是一个声明。
  • 您必须先“看到”项目声明才能使用它。
  • 重新声明是可以的(必须相同)。
  • 重新定义是一个错误(一个定义规则)。

答案 1 :(得分:3)

与类extern int i最接近的等同词是前向声明,您可以根据需要多次执行此操作:

class A;

class A;

class A;

class A{};

当您定义实际的类时, 表示构造它的实例需要多少内存,以及如何布局内存。不过,这不是真正的问题。

答案 2 :(得分:2)

第一个(extern)引用现有变量。所以你只是指出变量两次。

类声明赋予类型含义(您的类:A)。你试图给A赋予两个含义。这对你没用,而且只能混淆,所以编译器可以保护你免受它的侵害。

顺便说一句,如果你把两个类放在不同的命名空间中,你可以给它们相同的名字。

答案 3 :(得分:1)

你可以做到

class A;

随心所欲,然后在一个文件中用

定义它
class A { ... }

示例:
classB.h:

class A;
class B { A *a; }

classA.h:

class B;
class A { B *b; }

答案 4 :(得分:1)

你可以多次声明一个类和一个对象,你不能做的是定义它不止一次。

extern使这个声明而不是定义(因为没有初始化器):

extern int a;

正文使您的class定义,而不仅仅是声明。您可以定义一次类。

答案 5 :(得分:0)

但在第一种情况下并没有矛盾。

extern int i;
extern double i;

也不起作用。 因此,如果您按时间创建A类,则无法确定A是谁。

答案 6 :(得分:0)

我想真正的问题是'你为什么要这么做?'。当您在同一个翻译单元(.cpp文件)中多次包含头文件时,有时会出现这种情况。如果是这种情况,您应该考虑使用include guards来保持编译器满意。

这可能会给您带来问题的另一个原因是您使用的是第三方库,它定义了名称与您自己的类冲突的类。在这种情况下,您应该考虑使用命名空间来解决歧义。

在两种情况下'extern int i;'引用相同的对象(在别处声明),因此多个声明是明确的。如果你写了:

extern int i;
extern float i;

编译器会抱怨模糊性(因为如果你写'i = 0;',它就不知道你打算操纵哪个变量。

重复的类声明会导致声明不同;再一次,编译器在遇到“A foo”时会如何知道要使用哪一个?我想编译器可以比较类声明并验证它们实际上是相同的,但是当替代解决方案(命名空间,包括防护,重命名)变得如此简单时(这可能更少),这将是一项非常大的努力。最终阅读代码的人会感到困惑。)

答案 7 :(得分:0)

它与声明与定义无关。问题是类型与对象。

extern int i;

告诉程序,类型为int的对象存在,其名称为i。因为它是extern没有为它分配存储这里,但在其他地方,可能在另一个翻译单元中,它被定义并为其分配存储。

class A {
..
};

定义名为A类型。它不分配任何对象或变量。它在运行时完全没有区别,也没有为它分配存储空间,因为它不是一个对象。它只是向编译器引入了一个新的类型。从现在开始,您可以创建A类型的对象,他们将为其分配存储空间。

答案 8 :(得分:0)

我试了一下。我认为class不是数据类型,它是定义数据类型的启动器。

所以在

extern int i;
extern int i;

int是一种数据类型。所以我们重新声明一个变量而不是数据类型。

但是在

class A {...};
class A {...};

A是数据类型。我们正在重新定义一种数据类型,当然这是不允许的。