Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't the member func of nested class need a complete type?

Example:

 class A
{
  class B
  {
    A c;//error!A is an incomplete type
    void test() { A b;/*OK,but why?*/ }
  };
};

The code snippet seems strange for me,what's the difference between the two usage of A?

like image 523
scottxiao Avatar asked Apr 02 '18 04:04

scottxiao


2 Answers

As seen in the compile error:

prog.cpp:8:7: error: field ‘c’ has incomplete type ‘A’
     A c;//error!A is an incomplete type
       ^
prog.cpp:4:8: note: forward declaration of ‘class A’
  class A
        ^

Class A is a forward-declaration which:

Declares a class type which will be defined later in this scope. Until the definition appears, this class name has incomplete type. This allows classes that refer to each other:

For class A is not "fully" defined until class B is.

Thus, class A is a forward-declaration and an incomplete type.

However, for

void test() { A b;/*OK,but why?*/ }

If forward declaration appears in local scope, it hides previously declared class, variable, function, and all other declarations of the same name that may appear in enclosing scopes:

Thus, it is fine to have A declared in local scope.

like image 27
Joseph D. Avatar answered Sep 23 '22 23:09

Joseph D.


[class.mem]/6 specifies that:

A class is considered a completely-defined object type (6.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, noexcept-specifiers, and default member initializers (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.

The definition of an object (as in A b; or A c;) requires the object to have a complete type. As the paragraph above states, the class type is incomplete within its own definition, except in certain places: namely, inside member function bodies and a few other places.

This rule makes it possible to write nontrivial code inside member functions defined inline while also prohibiting a class from containing itself (directly or indirectly).

like image 189
Brian Bi Avatar answered Sep 23 '22 23:09

Brian Bi