以下代码确实编译,而名称“aNumber”在使用前未声明。
class A
{
A()
:aNumber(100)
{
}
void foo()
{
aNumber = 0;
}
int aNumber;
};
如果以上代码编译,那么为什么不遵循: -
A.
class Dummy
{
void foo(INT);
typedef int INT;
};
B.通过成员变量进行默认初始化: -
class Dummy
{
void foo(int y = x);
int x;
};
答案 0 :(得分:8)
答案 1 :(得分:2)
对于第1点:
$ 9.2 / 2 - “一个班级被认为是一个 完全定义的对象类型(3.9) (或完成类型)在结束时 类说明符。在课堂上 成员规范,类是 在功能内被视为完整 主体,默认参数和 构造函数ctor-initializers (包括嵌套的这类东西 类)。否则被视为 在自己的班级内不完整 构件规格“。
因此,必须在声明成员函数'foo'之前定义INT。
对于第2点: 这里的原因是'x'不是'Dummy'的静态成员。 Dummy的非静态成员需要一个对象表达式。
答案 2 :(得分:1)
以较少的前后传球处理语言最简单。在使用前定义事物也可以改善组织。
小型前瞻性声明可以引入更多实质性定义:
class Dummy
{
class bar; // declare first, but not a big deal
void foo(bar*);
class bar { ... };
};
样本“B”不受声明顺序的影响。它说明默认参数不能命名非静态成员。
答案 3 :(得分:1)
你在比较苹果和橘子。以下代码没问题:
class A {
A() :aNumber(100) { INT bNumber = aNumber; }
void foo() { aNumber = INT(42); }
void bar(int bNumber = INT(1)) { aNumber = bNumber; }
int aNumber;
typedef int INT;
};
问题不是你声明的,而是使用声明的地方。 方法定义,即使它们在词内部出现,也被编译为好像它们在类中声明,但在类声明之外和之后定义,因此是默认参数。
答案 4 :(得分:0)
标准定义了成员名称在其成员的某些部分中的范围。见3.3.6/1
:
- 在类中声明的名称的潜在范围不仅包括以下声明性区域 名称的声明符,但也包括所有函数体,默认参数和构造函数ctor- 该类中的初始值设定项(包括嵌套类中的这些内容)。
“潜在范围”是名称未被任何其他名称隐藏的范围。请注意,“遵循名称的声明符”是一个不太正确的术语,因为某些声明不是使用声明符声明的(例如,嵌套类声明)。所以C ++ 0x将其改为读取
在类中声明的名称的潜在范围不仅包括以下声明性区域 名称的声明点,[...]
另一个人引用了标准的另一部分(9.2/2
),要求类类型在某些部分被视为完整。例如,这允许您在成员函数体中创建类的对象。