以下是否相当于前瞻性声明?

时间:2012-02-05 09:54:28

标签: c++ forward-declaration

这与a recent question

有关

基本上是以下代码:

class A
{
    class B* b;
    B* c;
};

编译虽然class B未声明或正向声明。这种语法是否等同于前向声明?有什么不同吗?

3 个答案:

答案 0 :(得分:9)

您可以在同一声明中声明类型和对象。

class B* b;

声明一个类型B和一个对象b,它具有指向B的类型指针。类型是不完整的,并且在它发生的范围内被查找,如果查找未能找到类的现有声明,则类型在最近的封闭命名空间范围中命名一个类型(严格来说是非类非函数原型)范围,通常是命名空间)。该对象是声明出现的范围的成员(在本例中为class A)。

在大多数情况下,将完整类型和对象一起声明更为常见,在这种情况下,类型有时会保持匿名。 E.g。

struct { int a; int b; } x;

名称范围规则标准的相关部分是7.1.5.3 [dcl.type.elab]详细说明的类型说明符/ 2和3.4.4和3.3.1中引用的部分:

  

3.4.4描述了如何在 elaborated-type-specifier 中对标识符进行名称查找。如果标识符解析为类名枚举名 elaborated-type-specifier 会引入它进入声明的方式与 simple-type-specifier 引入其 type-name 的方式相同。如果标识符解析为 typedef-name 或模板 type-parameter ,则 elaborated-type-specifier 是不正确的。 [...]如果名称查找找不到名称的声明,则 elaborated-type-specifier 格式不正确,除非它是简单形式 class-key identifier 在这种情况下,标识符的声明如3.3.1。

中所述

答案 1 :(得分:1)

不,这是一个声明,指向B的指针。你不是在这里声明B,只是指向它的指针,而且它没有任何前瞻性。

修改:我错了,抱歉。见其他答案。

答案 2 :(得分:1)

我想补充一些细节来回答Charles Bailey

class A
{
public:
    class B * b;
    class C {} *c;
    int d;
} a;

B* globalB;
// C* globalC;  identifier "C" is undefined here

int main(int argc, char *argv[])
{
    a.d = 1;
    cout << a.d;
}

是的,它将不完整类型Bb定义为同时指向B的指针。但有趣的是:
“嵌套类声明的范围可见性的一个例外是类型名称与前向声明一起声明。在这种情况下,前向声明声明的类名在封闭类之外是可见的,其范围是被定义为最小的封闭非类范围。“Nested Class Declarations

这意味着类型B的定义超出了范围A,允许您定义变量globalB。如果您不希望将B定义在范围A之外,则可以使用{},就像我在示例中使用类型C一样。

顺便说一下,这个例子是正确的,其输出是:1