🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

C++ Workshop - Inheritance (Ch. 12)

Started by
39 comments, last by Dbproguy 16 years, 1 month ago
A nested class refers to a class a declared inside another class.
A derived class refers to a class that inherits from another class.

I have never seen a class that is both nested in and derived from the same class.

If you are referring simply to inheritence; use as many classes as you need. However, follow a piece of sage advice from Scott Myers, C++ guru: Make non-leaf classes abstract. That is; if anything derives from a class, make it abstract. Only leaf classes should be instantiatable.
Furthermore, don't derive just because it's convienent. You should be deriving because it's the logical thing for the concept the class represents, not just to reuse code.
Advertisement
Sorry about the confusion. I meant the question to refer to having one class defined within another, then within another and then within another etc., such as the Mammal, Pet, Dog example that I gave. I guess it could go on to specific breeds or colours of dogs.

I suspect that it wouldn't be wise to have 100 such classes declared each within the previous one, so what would be a maximum that folks would say was both necessary and practical? I suspect that it would be in single figures, but that's just a wild guess.
Again, the answer is 'however many is correct for your design'. There is no 'Don't nest classes more than five deep!' rule of any sort beyond the general 'If you do this, your design is a bit odd.'

Furthermore, the 'mammal, pet, dog' example sounds like an inheritence sequence. Pick a better example.
Quote: Original post by CondorMan
There is reference in a couple of places that "nested" derived classes are possible (Mammal, Pet, Dog etc.) but is there a restriction on the number of such nested classes imposed by the language or compiler? I suspect that the answer is no and, if that's the case, any restriction is self-imposed by the programmer in the interest of being able to read and understand the code.

If my assumption is correct, what would folks say is a reasonable maximum number of nested derived classes, for instance when creating a really large and complicated application?


[advanced]
There is no standard restiction on the number of derived classes. To be more precise, the C++ standard don't force the compiler vendors to implement neither a minimum inheritance depth nor a maximum inheritance depth. The maximum it can do is to provide some sample numbers that should be supported by a reasonable implementation of the standard - but these are guidelines, not enforced rules.

Anyway, you don't have to worry about this issue: be sure that the maximum inheritance depth supported by your compiler (is such limitation exists) is way beyond what you'll ever do.
[/advanced]

From a design point of view, there is no reasonable maximum number of derived classes. Inheritance is used to express a particular relationship between two classes ("is-a"). Whenever this relastionship exists, using inheritance is a viable design option. If such relationship don't exist, don't use inheritance. That's as simple as that.

If I take (for examples) the project I worked on, sometimes inheritance is heavily used (some classes might have more than 10 ancestors), sometimes it is very lightly used (1-2 ancestors at most). It merely depends on the environment (MFC-based programs tends to be very derivation-oriented, while program buit using the STL tend to be composition-oriented) and on the perso who does the design (some guys tend to overuse inheritance, while some other guys (like me) try to express their solution using composition instead of inheritance).

Regards,
As a practicle working example, my current project has a heirarchy with 57 classes. But the heirarchy is only 2 levels deep. There is a single abstract base class, and all 56 other classes are derived directly from it. I find this sort of arrangment much more common than the other extreme; many classes, each derived from the one before it, creating a single long chain of derived classes.

(Incidentally, that huge set of classes also makes heavy use of composition, with derived classes holding instances of other classes in the same heirarchy; it's a GUI widget library)
Thank you. When I started to read this response, I thought "how on earth does he keep track of 57 classes, one within the next", and then I read on. That's exactly the sort of information that I was seeking (for future use), and shows even more self-restraint than I was expecting!
Greetings All!

It's once again QUIZ TIME!!! That's right, listed below are a set of quiz questions to help you test your knowledge and understanding of the material contained in chapters 12.

In addition to the questions and exercises below, make sure that as you're reading the book you enter the examples into your compiler, build the program, and run the executable. I know this is a time consuming process, but the repeat use of keywords, syntax, and semantics will help ingrain the information into your long-term memory. My advice is to create a simple "driver" project with a function main. As you read, enter the examples into function main, test it, and then erase it for use again in the next example.

PLEASE DO NOT POST THE ANSWERS TO THESE QUESTIONS OR EXERCISES. If you are unable to answer these questions, please ask for assistance, but DO NOT POST THE ANSWERS. Any question which is not marked with [Extra Credit] can be answered by reading your textbook. Questions which are marked [Extra Credit] either have been answered in the thread previously, or can be answered by doing a bit of research.

I will create an answer thread for these questions immediately, so that people will have a chance to get the answers more quickly.

Chapter 12 Quiz

1. What is derivation?
2. What happens if you try and derive from a class which has not yet been declared.
3. What is the purpose of declaring member variables as protected?
4. When instantiating an object which is derived from one or more base classes, which constructors are called, in what order?
5. What about destructors? What order are they called in.
6. What is it called when a derived class replaces the functionality of a base class with its own implementation?
7. If you’ve overridden a method in a derived class, is it still possible to access the base class version? If so, what’s the syntax?
8. What does declaring a method as virtual do?
9. Can virtual functions be used on non-pointer, non-reference variables?
10. When should you declare the destructor of your class as virtual? What happens when you delete a base pointer to a derived class with a non-virtual destructor.
11. Can constructors be virtual? Can copy constructors be virtual?
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
is there anything to the virtual keyword? i really see no purpose for it at this point.
It may just be me, or that this is completely new, but when would you declare a function in a class to be "virtual"?

I don't see what these copy constructors do.
Mammal::Mammal (const Mammal & rhs):itsAge(rhs.GetAge())
what does this line do? I don't see it being used in the sample code on 400-402 (although if it is, I couldn't recognize it), but somehow the print statement in there is still called.



maybe this will help me figure out what the virtual keyword is then.
I will not explain about virtual, could not do that to myself :-/
java and python do not have any notion of virtual or rather all
methods are virtual.



Mammal::Mammal (const Mammal & rhs):itsAge(rhs.GetAge())

can be changed to read

Mammal::Mammal(const Mammal& rhs){  itsAge=rhs.GetAge();}


if operator= exists.

the stuff after : can be translated to:
call itsAge's constructor with the result of rhs.GetAge().
Quote: Original post by Demos
is there anything to the virtual keyword? i really see no purpose for it at this point.
It may just be me, or that this is completely new, but when would you declare a function in a class to be "virtual"?

I don't see what these copy constructors do.
Mammal::Mammal (const Mammal & rhs):itsAge(rhs.GetAge())
what does this line do? I don't see it being used in the sample code on 400-402 (although if it is, I couldn't recognize it), but somehow the print statement in there is still called.



maybe this will help me figure out what the virtual keyword is then.


how I understand it is the main way you use virtual functions is in working with multiple classes at runtime with unknown types

IE

With the virtual Speak() function the book you can create a Mammal pointer, and iterate through an array of Mammals. At each index it calls Speak, and if the pointer actually points to a Mammal::Dog, it will call Dog.Speak() without you knowing or having to worry about it.

More specifically to our project, I think it will come in handy when working with different types of items (potions, weapons, armor, quest items, etc.) when you attempt to use an item, your programm will be able to call the specific type's Use() function without knowing what the type is explicitly.

This topic is closed to new replies.

Advertisement