2010-08-30 49 views
2

以下代码不会编译,而名称“aNumber”在使用前未声明。声明在使用C++之前?

class A 
{ 
    A() 
     :aNumber(100) 
    { 
    } 
    void foo() 
    { 
     aNumber = 0; 

    } 
    int aNumber; 
}; 

如果上面的代码编译,那么为什么不以下: - 由成员变量

A. 
class Dummy 
{ 
    void foo(INT); 
    typedef int INT; 
}; 

B.Default初始化: -

class Dummy 
{ 
    void foo(int y = x); 
    int x; 
}; 

回答

1

你在比较苹果和橘子。下面的代码是OK:

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

的问题不是你声明一下,但如果使用的声明。 方法定义,即使它在词类中出现在类中,也会被编译,就好像它们是在类中声明的一样,但在类声明的外部和后面定义,因此是默认参数。

+0

class A {A():aNumber(aStaicMember){} int aNumber; void foo(int x = aStaicMember); // aStaicMember还没有被decalred静态int aStaicMember; //声明}; int A :: aStaicMember = 100; //定义当上面是真的那么为什么不是typedef,我仍然感到困惑 – 2010-08-31 10:10:46

+0

我已经显示你的typedef也是可以的,重要的部分是_where_你使用的名字,而不是名称是typedef还是别的.chubsdad引用了相关的标准文本9.2/2。 – MSalters 2010-09-01 08:25:54

1

最简单的方法来处理语言较少前置式返回通行证。在使用之前定义事物也会改善组织。

更多实质性的定义可以通过一个小前锋声明中介绍:

class Dummy 
{ 
    class bar; // declare first, but not a big deal 
    void foo(bar*); 
    class bar { ... }; 
}; 

样品“B”不受声明的顺序。它说明了一个默认参数不能命名非静态成员。

8
  1. 在编译案例中,类中元素的顺序是不相关的。
  2. typedef的情况下,订单与IS有关,因为在该范围之外可见的名称可能会被新的typename覆盖。
  3. 第三个例子不合格,你不能用非静态成员变量初始化。
2

对于点1:

$ 9.2/2 - “的一类是在 类级闭合}认为是 完全定义的对象类型(3.9) (或完整的类型)符。在类 成员的规范,该类是 视为完整的函数内 机构,默认参数和 构造函数构造函数,初始化 (包括嵌套 类这样的事情),否则被认为是如 其自己的类内不完整 成员规范。“

因此INT必须在成员函数'foo'声明之前定义。

对于第2点: 这里的原因是'x'不是'Dummy'的静态成员。 Dummy的非静态成员需要一个对象表达式。

+0

对于第2点,我可以使用如下: - class Dummy { void foo(int y = this-> x); int x; }; 不,我不能! 为什么我不能? – 2010-08-31 08:48:08

+0

这解释了什么标准说,但我仍然不知道为什么它是这样的原因。“$ 9.2/2”。 当“类被视为在函数体内完成,默认参数和构造函数ctor-initializers”那么为什么不为函数声明? – 2010-08-31 09:27:29

+0

@Sudhendu Sharma:'this'不能用于所示的默认参数声明中,因为'this'仅在'定义'或非静态类成员函数和构造函数初始化列表中有效。 – Chubsdad 2010-08-31 09:48:23

0

该标准定义了成员名称在成员某些部分范围内的地方。见3.3.6/1

  • 在一个类中声明的名称的潜在范围不仅包括以下 名称的说明符声明区,也是所有函数体,默认参数,并构造ctor- 初始化的在这个类中(包括嵌套类中的这些东西)。

“潜在范围”是范围的名称有,如果它不是由任何其他名称隐藏。请注意,“在名称的声明符后面”是一个不太正确的术语,因为某些声明没有使用声明符声明(例如,嵌套的类声明)。所以的C++ 0x改变了这种阅读

在一个类中声明的名称的潜在范围不仅包括以下 的名称的申报点的声明区,[...]

另一个人引用了标准的另一部分(9.2/2),这要求在某些部分认为类类型是完整的。例如,这允许您在成员函数体内创建类的对象。