Nested classes

Hi. I'm starting to get a fair handle on C++ now but the one thing that seems to completely baffle me is nested classes. I can understand composition, thats no problem at all but why on earth would anyone want to include a class definition inside another class.Its not like the inner class is only accessible to the outer class and also the inner class has no access to outers members and vice versa.
So why nest classes?
Should I do this with my classes?
Are there any benefits to nesting classes?
Is it just me or do nested classes lead to more confusing sourcecode in general?

Comments

  • I do not recommend nesty classes. If need to group data types into one object, then consider a struct.

    Kuphryn
  • : I do not recommend nesty classes. If need to group data types into one object, then consider a struct.
    :
    : Kuphryn
    :

    Your missing the point. Stroustrup recommends them and the STL is full of them. So why are nested classes used and how can they help me?
    Besides in C++ a struct barely differs from a class,it can be inherited from,have constructors,and in turn hold other nested structs. So I ask again. why do this?
  • [b][red]This message was edited by kuphryn at 2002-9-30 22:14:19[/red][/b][hr]
    Why do you think nested classes are used?

    Kuphryn


  • [b][red]This message was edited by Darius at 2002-10-1 0:51:29[/red][/b][hr]
    : Hi. I'm starting to get a fair handle on C++ now but the one thing that seems to completely baffle me is nested classes. I can understand composition, thats no problem at all but why on earth would anyone want to include a class definition inside another class.Its not like the inner class is only accessible to the outer class

    Where on earth did you get that belief? The following won't (shouldn't) compile, due to an access error on A::B. If the inner classes definition is private then it IS only accessible from the outer class.

    [code=333333]
    [color=cd5c5c]#include [/color][color=ffa0a0][/color]

    [color=f0e68c][b]using[/b][/color][color=ffffff] [/color][color=bdb76b][b]namespace[/b][/color][color=ffffff] std;[/color]

    [color=bdb76b][b]class[/b][/color][color=ffffff] A{[/color]
    [color=f0e68c][b]public[/b][/color][color=ffffff]:[/color]
    [color=ffffff] [/color][color=bdb76b][b]void[/b][/color][color=ffffff] doAandB(){ cout<<[/color][color=ffa0a0]"A"[/color][color=ffffff]<<endl; m_B.doB(); }[/color]

    [color=f0e68c][b]private[/b][/color][color=ffffff]:[/color]
    [color=ffffff] [/color][color=bdb76b][b]class[/b][/color][color=ffffff] B{[/color]
    [color=ffffff] [/color][color=f0e68c][b]public[/b][/color][color=ffffff]:[/color]
    [color=ffffff] [/color][color=bdb76b][b]void[/b][/color][color=ffffff] doB(){ cout<<[/color][color=ffa0a0]"B"[/color][color=ffffff]<<endl; } [/color]
    [color=ffffff] };[/color]
    [color=ffffff] B m_B;[/color]
    [color=ffffff]};[/color]

    [color=bdb76b][b]int[/b][/color][color=ffffff] main(){[/color]
    [color=ffffff] A::B b;[/color]
    [color=ffffff] A a;[/color]
    [color=ffffff] b.doB();[/color]
    [color=ffffff] a.doAandB();[/color]
    [color=ffffff] [/color][color=f0e68c][b]return[/b][/color][color=ffffff] [/color][color=ffa0a0]0[/color][color=ffffff];[/color]
    [color=ffffff]}[/color]
    [/code]

    and also the inner class has no access to outers members and vice versa.

    Why should it? Classes are supposed to be black boxes. If I make a Scrollbar that it made of three Buttons and a Label, does the Scrollbar class need to see inside of Button or Label, does the Button or Label class need to see inside of Scrollbar? In this case, likely Button or Label won't be nested classes, but what if I replace one of those Buttons with a Scrolltab class that is only necessary for Scrollbar.

    : So why nest classes?

    Information hiding.

    : Should I do this with my classes?

    If it's appropriate. Look at it this way. You define your interface and the insides are left up to you. Once your writing code for the inside of your class it's like writing for a different program and you can use all the tools you would for a normal program. If some part of the inside of the class would benefit from being encapsulated in a class do so. Since your interface is already defined likely that specialized class will have nothing to do with the outside and shouldn't be seen by the outside.

    : Are there any benefits to nesting classes?

    Information hiding, plus the benefits of OOP for the internals of your classes.

    : Is it just me or do nested classes lead to more confusing sourcecode in general?

    It shouldn't, unless you believe OOP leads to more confusing sourcecode in general. You are simply using OOP for the inside of your classes.

    "We can't do nothing and think someone else will make it right."
    -Kyoto Now, Bad Religion





  • Thanks darius. Thats shedded some light on the subject.If only Stroustrup was as lucid about the subject as you. I hadn't considered the fact that you could make the class definition private and so encapsulate inner into outer. Do I take it from this that there is no reason at all to have a public nested class.
    Later today as an exercise to see how im coping with template classes I intend to make a linked list template class. Now should the Node class be privately nested in the list class to facilitate encapsulation, i.e. the nodes will only be used by the list class so why give user direct access to it,or should I make the node class a totally separate template class from the list class. Although c++ is easy enough to learn from books as a language I am really struggling on the design aspects of things. I still dont think Im "thinking in objects" yet properly.
    On another note I want to know how you would deal with exceptions if you wrote your own list class. I still find exceptions a little confusing. Should a list template class define a nested exception class to throw if an exception occurs? What should I do in the event a new node cannot be made for whatever reason? Are there any other exceptions to consider besides new failing?
  • One solution to an exception is to create your own exception class and then throw it.

    Kuphryn
  • : Thanks darius. Thats shedded some light on the subject.If only Stroustrup was as lucid about the subject as you. I hadn't considered the fact that you could make the class definition private and so encapsulate inner into outer. Do I take it from this that there is no reason at all to have a public nested class.

    There are reasons to have public nested definitions (for example, the iterator types of STL containers). The gain from this is lessening the pollution of the namespace and centralizing aspects related to your object TO your object. Just make sure you understand that if it's public it's part of your interface.


    : Later today as an exercise to see how im coping with template classes I intend to make a linked list template class. Now should the Node class be privately nested in the list class to facilitate encapsulation, i.e. the nodes will only be used by the list class so why give user direct access to it,or should I make the node class a totally separate template class from the list class.

    This was actually one of the examples (though not templated for simplicity) I was thinking of giving as a GOOD example of when to use private nested classes. I either forgot to add it or decided against it (I don't remember). As a general programming principle, you typically want to try to keep the declaration/definition of something close to where it is used. In this case, having a separate class would be less than preferable.

    Although c++ is easy enough to learn from books as a language I am really struggling on the design aspects of things. I still dont think Im "thinking in objects" yet properly.
    : On another note I want to know how you would deal with exceptions if you wrote your own list class. I still find exceptions a little confusing. Should a list template class define a nested exception class to throw if an exception occurs?

    If it's appropriate. In the case of a generic container (e.g. your templated list) exception-wise you typically want your class to be exception-safe and exception-neutral. Exception-safe means that if an exception is thrown by the class or by any elements contained in the class, the class should still be in a reliable, defined state. An example that is NOT exception-safe, is a list that sets it end pointer to a new node, then creates the data to fill that node. If the data is a class and throws an exception upon creation, you now have a pointer to nowhere, which is not a reliable well-defined state for a list. Exception-neutral simply means that the class lets exceptions from the internal classes pass through. So, if, say, you have a list of stacks (there may be some use for that...) and one of the stacks throws an Underflow exception, you want that to be passed all the way up to the user of the container class. This does not mean that your class can't have it's own exceptions. That self-same stack could be a generic container, but it would make sense for it to throw an underflow exception.

    :What should I do in the event a new node cannot be made for whatever reason?

    It depends on your implementation, but assuming a relatively straightforward implementation where the only way a new node could NOT be created is due to a) memory, or b) the templated class fails (via throwing an exception) upon construction. Then the proper thing to do would be to have your list be exception-neutral. I.e. you really don't need to do anything you just let the exceptions pass through. (However, you DO need to do something to make your class exception-safe and that may involve catching some exceptions, cleaning up, and then rethrowing the exception you caught). My philosophy in general for memory exhaustion exceptions is to never handle them and always let them pass up to the user (where they should be handled). For a large system where running out of memory is likely or there is a mechanism for dealing with memory exhaustion (e.g. a web server or database), then obviously they should be handled, though probably at a high-level (i.e. a "tool" class probably won't be handling it).

    :Are there any other exceptions to consider besides new failing?

    For a templated class you are in a special predicament. You have NO idea what you will be templated on, therefore anything could happen. Classes can throw exceptions in their constructors, you could have an exception thrown simply by making a local copy of the templated type. This is why generic container classes can be very difficult to make exception-safe and exception-neutral. Hmm, difficult is not quite the right word, more correctly, it takes a good level of care and attention to detail. However, the main exceptions you should be worried about is memory exhaustion and constructors throwing exceptions, the latter being impossible for you to appropriately handle in a generic class, but you shouldn't be handling it. Basically, whenever you write any line of code think "could this throw an exception?" and also think "if an exception is thrown here, is my class still in a reliable state?". As I said, this can be VERY tricky to get right, and it is very easy to get wrong.


    "We can't do nothing and think someone else will make it right."
    -Kyoto Now, Bad Religion

  • This is a very interesting discussion. I feel as if im understanding when to nest classes now. Im going to try and code up this template class today if I get the time and I'll post it here later for comments.
    Thanks again darius. You seem to have the ability to make hard concepts simple to understand which is a rare trait in anybody.
  • [b][red]This message was edited by Darius at 2002-10-1 9:24:7[/red][/b][hr]
    : This is a very interesting discussion. I feel as if im understanding when to nest classes now. Im going to try and code up this template class today if I get the time and I'll post it here later for comments.
    : Thanks again darius. You seem to have the ability to make hard concepts simple to understand which is a rare trait in anybody.
    :

    Hmm, :P. I find this odd, to my experience I consider myself a horrible teacher. No one seems to understand what I say :P.

    However, on a related topic, I should thank you for having a good question (resulting in an interesting for me as well as you discussion). These are more the questions I like. Suffice to say questions along the line of "HELP!", "My instructor gave me exercise 1.5b what's the answer?", or "Where can I find / Can you give me the source code to ...?" piss me off (Okay, actually I typically just ignore them and they only minorly annoy me, but you get the idea).

    "We can't do nothing and think someone else will make it right."
    -Kyoto Now, Bad Religion



Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories