我可以这样做
extern int i;
extern int i;
但是我不能用类
做同样的事情class A {
..
}
class A {
..
}
虽然在这两种情况下都没有分配内存。
答案 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)
所以在
extern int i;
extern int i;
int是一种数据类型。所以我们重新声明一个变量而不是数据类型。
但是在
class A {...};
class A {...};
A是数据类型。我们正在重新定义一种数据类型,当然这是不允许的。