It's a plane, It's a train… It's a C++ elaborated type specifier!
Written on June 15, 2009, by Milot Shala.



As we programmers know C++ is very expressive and powerful programming language, sometimes you feel that you have your compiler in your hands and you must teach it how to behave like a little child, and yes, this is true.

These days I am hacking on some random projects in my spare time and I came up with something that confused me, some function names are identical with some class names and sometimes C++ compiler allows that, but how this can be achievable?

C++ use elaborated type specifiers to tell the compiler explicitly to treat a class as a class, and this will be described technically in the following paragraphs.

I have created a situation using the Factory pattern (see: Factory Pattern). In our case you have a Child class and when some piece of code needs an object instance of Child class, the Factory class creates a Child object instance and returns it via createChild() method.

Here is the implementation of Child class, basically it does nothing just prints out a message:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Child
{
public:
  Child();
  void printGreetingMessage();
};
 
Child::Child()
{
}
 
void Child::printGreetingMessage()
{
   std::cout << "Greetings from a Child class\n";
}

To achieve the goal you must have a Factory class which has two methods one for creating a Child object and second for destroying it, the function for creating the object returns a pointer to Child class.

Before continuing to the Factory class implementation, suppose that you have some header file included in this source file that has a function named Child():

1
2
3
4
inline void Child()
{
  std::cout << "Greetings from a function with the same name\n";
}

While you are designing your Factory class you run into compile-time errors telling you that you must be more careful with this one, this is because if try to declare a class in the standard way the compiler cannot identify a class and a function that possess the same name, you must be more specific to the compiler in this situation telling compiler that the following Child class is a class by specifying class keyword in front of the class type:

1
2
3
4
5
// when creating a Child object
class Child _child;
 
// when calling Child function
Child();

and here is complete code for a Factory class using elaborated type specifier:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Factory
{
public:
  Factory();
  ~Factory();
  class Child* createChild(); // return pointer to Child object
  void destroyChild();  // destroy created object
 
private:
  class Child *_child; // declare pointer to child object
};
 
Factory::Factory()
{
}
 
Factory::~Factory()
{
  destroyChild();
}
 
class Child *Factory::createChild()
{
  _child = new class Child(); // create instance of a Child class and return it's pointer
  return _child;
}
 
void Factory::destroyChild()
{
  delete _child; // free the mallocs!
}

Main function using elaborated type specifier for Child class:

1
2
3
4
5
6
7
8
9
10
11
int main()
{
 
  Factory f;
  // still using elaborated type specifier
  class Child *real_child = f.createChild();
  real_child->printGreetingMessage();
  Child();
 
  return 0;
}

After compilation output:

1
2
3
4
milot@lambda:~/Desktop$ ./elaborate
Greetings from a class
Greetings from a function with the same name
milot@lambda:~/Desktop$

After you received this information, don’t try this in a real project, it may cause headaches and is not recommended to use such construct but you can use it if necessary, as for me, I barely use this construct, but sometimes I find it useful.

blog comments powered by Disqus

958 views

© Copyright Phalanx Blogosphere - Powered by Wordpress - Phalanx logo is designed by Leopard Cana