|
|
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.
958 views

