Class Names


Structures, classes and functions share the same name space within the scope of their declarations; however, this does not preclude the possibility of a class and function sharing the same name and still being syntactically distinguishable. To see how this can be, consider the following example.

struct test {int i;};
 
void test(struct test* pointer_test);  // redefines 'test' as a function and uses an
                                       // elaborated type specifier for parameter declaration
 
void f()
{
 struct test* pointer_test;  // must use elaborated type specifier to use structure test
 test(pointer_test);         // function test is called, it is the 'most' visible
}

An elaborated type specifier can be used to indicate to the compiler that a class or an enumerated type is that which is being referenced, in preference to a more recently defined object of the same name. The syntax of elaborated type specifiers is defined in the topic titled type (of the subsection on declaration specifiers).

Another use to which elaborated type specifiers can be put is to avoid deadlocks when declaring classes. Consider the following example.

class transform;
 ...
class point
{
 public:
  ...
  point& operator*=(const transform& transform_multiply);
   
 private:
  int array_integer[2];
};
 ...
class transform 
{
 ...
 private:
   fixed array_fixed[4];
   point point_transform;
};

The class point defines an operator*= for the class transform; yet the class transform is defined in terms of the class point (point_transform). Therefore, a mechanism is needed to avoid the circularity in the declaration process. The name of the class transform is introduced via an elaborated type specifier prior to the declaration of the class point. The class transform is then declared after the class point. An example resembling this but with an additional twist is shown below.

struct test {int i;};   // structure test with global scope
 
void f()
{
 struct test;                                  // another structure test, this time with local scope
 test* pointer_test_local;                     // declares a pointer to the local test structure
 struct test {char* pointer_character_test;};  // now defines the local structure test
}

Inside the function f, the structure test is declared using an elaborated type specifier. The form used is that of "class_key identifier" (as documented in the topic type of the declaration specifiers subsection). The local forward declaration of the structure test hides the global declaration of the structure with the same name. Two statements later, the local version of the structure test is defined. The second statement within the function f declares a pointer to the local version of test - prior to its definition. As a final example, consider the following statement.

class straight_away * straight_away;

This example declares a class straight_away and immediately redefines the name straight_away to be a pointer to the class straight_away. Of course, an elaborated type specifier is then required to access the class straight_away, in preference to the pointer straight_away, since the latter's name hides the name of the former. This example serves to illustrate yet another point, the name of a class is defined (and can be used) immediately after its identifier has been encountered by the compiler.