开发者

Declare Before use in C++?

Following code does compile whereas name "aNumber" is not declared before use.

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

    }
    int aNumber;
};

If above code compiles then why not following :-

A.
class Dummy
{
    void foo(INT);
    typedef int开发者_运维百科 INT;
};

B.Default initialization by member variable :-

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


  1. In compiling case the order of the elements in the class is irrevelant.
  2. In case of a typedef the order IS relevant, because a name that was visible outside of the scope might be covered by the new typename.
  3. The third example is ill-formed, you cant initialize with a non-static member variable.


For point 1:

$9.2/2 - "A class is considered a completely-defined object type (3.9) (or complete type) at the closing } of the class-specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments and constructor ctor-initializers (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification."

Therefore INT has to be defined before the member function 'foo' is declared.

For point 2: The reason here is that 'x' is not a static member of 'Dummy'. A non static member of Dummy needs an object expression.


You're comparing apples and oranges. The following code is 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;
};

The problem is not what you declare, but where the declarations are used. Method definitions, even it they appear lexically inside a class, are compiled as if they are declared inside the class, but defined outside and after the class declaration, and so are default arguments.


It's easiest to process the language in fewer front-to-back passes. Defining things before use improves organization, too.

More substantial definitions can be introduced by a small forward declaration:

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

Sample "B" is not affected by the order of declaration. It illustrates that a default argument cannot name a nonstatic member.


The Standard defines the places where a member name is in scope in certain parts of its members. See 3.3.6/1:

  • The potential scope of a name declared in a class consists not only of the declarative region following the name’s declarator, but also of all function bodies, default arguments, and constructor ctor- initializers in that class (including such things in nested classes).

"Potential scope" is the scope that the name has if it isn't hidden by any other name. Note that "following the name's declarator" is a not quite correct term, because some declarations are not declared using a declarator (nested class declarations, for example). So C++0x changed this to read

The potential scope of a name declared in a class consists not only of the declarative region following the name’s point of declaration, [...]

Another guy quoted another part of the Standard (9.2/2), that requires the class type to be regarded as complete at certain parts. This allows you to create objects of your class within member function bodies, for example.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜