Anmol444 wrote: |
---|
Also the use of a Pure Virtual Functions. One is forcing its derived classes to define it, if you do force them to define it that means that if they do not, they cannot call the base right? |
A class can abstract - which means one cannot create an object of that type, because it contains a pure virtual function that by definition is not defined, and MUST be defined by derived classes. If a derived class does not define it - then it is a compile error.
If it is an ordinary virtual function, and the derived class does not define it, then the compiler will use the next available function that is defined in terms of working it's way up the inheritance tree from the derived class.
Anmol444 wrote: |
---|
The other one, that was not in my book that I think could be useful is that if you had a array of pointers to the base you could polymorphically use each derived class's function. |
They don't have to be pointers to base, they would be pointers to the derived class objects - which is what you have in your code. It's just that pointers to derived are valid pointers to base.
This is a very handy feature of C++. Imagine you have a RPG where you have lots of Players, Enemies & Weapons, all in a big inheritance tree. Now you can declare an attack function which takes pointers to each 3 of these, and when you call the function you send the pointers of the concrete objects (that is the actual individual thing) . So now you don't have to write overloaded functions to accommodate every combination of objects. This particular example would probably work best with a Command (aka Action) Design Pattern.
The use of polymorphism like this is one situation where you do have to have an inheritance tree, otherwise one should probably prefer to make use of composition instead.
Another example which uses polymorphism is in a package that does unit conversions. I had an inheritance tree of units split up into their types - Angles, Distances, Areas, Temperature, Volume etc. I had 2 pure virtual functions in the base class - ToMetric & FromMetric, which took pointers to a Unit object. Each derived class redefined these functions to do their particular conversion. To do a conversion from one type to the other, convert to metric, then convert to the other type. For example, to go from Yards to Feet, convert Yards to Metres, then Metres to Feet. Sounds convoluted, but it is actually more efficient this way - if one had 10 units, then there is a need for 19 functions as opposed to 90. Btw boost has a whole conversion library which does mixtures of unit types, and being a professionally written library is vastly superior to my little example.
With your code, m_strName shouldn't be protected IMO. Rather it should be private, and you generally access it in the derived classes via an interface function in the base class. Although you can still use the initialiser list like you are doing now. You have an interface function called GetName, but instead you could have a member function that does the printing out. So you would call this function rather than using a get function in main().
We had a huge discussion about get & set functions here:
Here are some of the more relevant parts:
Not all of what I said there was right (esp. the Send / Receive functions) - I saw the light a bit later - thanks to
ne555 8+) here:
Also it might be educational to read the replies to what I said.
Hope this helps :)