Jump to content

  • Log In with Google      Sign In   
  • Create Account

when should I use nested class in c++ and why?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
15 replies to this topic

#1 jhq   Members   -  Reputation: 133

Like
0Likes
Like

Posted 17 November 2007 - 08:27 AM

Hi, as the title suggested, in which situation should I choose the nested class/struct(as well as enum, typedef, etc) rather than place the defininition outside a certain class. Since there is few difference between the two from the syntax point of view, I believe the choice hugely depends on personal convention and experience. So from the "design" point of view, what is your choice? Thanks in advance ;)

Sponsor:

#2 Simian Man   Members   -  Reputation: 1010

Like
0Likes
Like

Posted 17 November 2007 - 08:38 AM

I usually use nested definitions if the thing your defining is logically a part of the outer class. ie if it does not make sense to use it without the outer class. Of course that itself is a subjective decision :)

#3 BlodBath   Members   -  Reputation: 150

Like
0Likes
Like

Posted 17 November 2007 - 08:43 AM

Typically I use nested classes for 'hiding' classes that the parent can dispatch. SC++L uses this approach for iterators, where the iterator is dispatched from the parent container class to be specialized for the instance of the container. In my own experience its not terribly useful, however I've used a nested class to hide the API for a small 3D framework, which suits the pattern pretty well.

#4 jhq   Members   -  Reputation: 133

Like
0Likes
Like

Posted 17 November 2007 - 09:03 AM

Quote:
Original post by Simian Man
I usually use nested definitions if the thing your defining is logically a part of the outer class. ie if it does not make sense to use it without the outer class. Of course that itself is a subjective decision :)

Yeah, in practice, sometimes it's too subtle to tell whether or not it is "logically a part of the outer class". Just follow your inituition and experience.

Quote:
Original post by BlodBath
Typically I use nested classes for 'hiding' classes that the parent can dispatch. SC++L uses this approach for iterators,


But in STL we can directly use iterator from outside, so what are it "hiding" for? To be more specific, what's the difference if iterator is defined outside the container in STL?




#5 Sneftel   Senior Moderators   -  Reputation: 1781

Like
0Likes
Like

Posted 17 November 2007 - 09:09 AM

Quote:
Original post by jhq
Since there is few difference between the two from the syntax point of view

There is one gigantic difference: inner classes can access private class members. That means that an inner class can communicate with its outer class without having to go through the outer class' public interface. Because of this, making a class an inner class should be thought of as increasing the size of the class (a bad thing) while complicating its responsibilities (also a bad thing). Because of this, a class should be an inner class ONLY where it cannot reasonably be implemented using the outer class' public interface.

Some people like to make things inner classes just because they relate to the outer class or are "part of" the outer class. This is NOT a good idea. Making something an inner class is not a good way of providing namespacing, because of the extra privileges and responsibilities that doing so confers on the class.

Inner classes are also the correct way to implement the Observer pattern. Because of the amount of code required to do this without lexical scoping, however, it's rare to actually see this.

#6 yahastu   Members   -  Reputation: 152

Like
0Likes
Like

Posted 17 November 2007 - 09:20 AM

Quote:
Original post by Sneftel
Some people like to make things inner classes just because they relate to the outer class or are "part of" the outer class. This is NOT a good idea. Making something an inner class is not a good way of providing namespacing, because of the extra privileges and responsibilities that doing so confers on the class.


std::vector<int> nums;
std::vector<int>::iterator = nums.begin();

It seems that the designers of the Standard Template Library completely disagree with you!

I personally think it is a good way to provide namespacing, and moreover, it allows you to keep an internally used class completely private...which you couldn't do otherwise.

#7 phantom   Moderators   -  Reputation: 7565

Like
0Likes
Like

Posted 17 November 2007 - 09:28 AM

It seems you've miss understood the definition you posted, opening up the "vector" header from VC++8 show this;


typedef _Vector_iterator<_Ty, _Alloc> iterator;



in the vector class.

The type, _Vector_iterator, is defined earlier in the header file and is NOT an inner class of Vector.

#8 rip-off   Moderators   -  Reputation: 8727

Like
0Likes
Like

Posted 17 November 2007 - 09:30 AM

Quote:
Original post by yahastu
Quote:
Original post by Sneftel
Some people like to make things inner classes just because they relate to the outer class or are "part of" the outer class. This is NOT a good idea. Making something an inner class is not a good way of providing namespacing, because of the extra privileges and responsibilities that doing so confers on the class.


std::vector<int> nums;
std::vector<int>::iterator = nums.begin();

It seems that the designers of the Standard Template Library completely disagree with you!

I personally think it is a good way to provide namespacing, and moreover, it allows you to keep an internally used class completely private...which you couldn't do otherwise.


Consider std::list::iterator. Or std::map::iterator. How would one implement it without exposing too much in the public interface? std::vector has one of the few iterators that can be implemented using its public interface.


#9 yahastu   Members   -  Reputation: 152

Like
0Likes
Like

Posted 17 November 2007 - 09:31 AM

(embarrassed) oops!

#10 jhq   Members   -  Reputation: 133

Like
0Likes
Like

Posted 17 November 2007 - 10:06 AM

OK, now I have deeper understanding about nested class. But what about those nested enum and typedef? Is there anything special I need to pay attention to? Or it just all depends on your convention?

#11 Sneftel   Senior Moderators   -  Reputation: 1781

Like
0Likes
Like

Posted 17 November 2007 - 10:19 AM

Quote:
Original post by yahastu
It seems that the designers of the Standard Template Library completely disagree with you!

Well, a few answers to this.

1. As others have mentioned, for some containers it's necessary.
2. The STL has many implementations. Making it a free class would have forced an implementation decision on all of them.
But, the important one...

YES! The designers of the C++ Standard Library made a lot of BAD DECISIONS. They weren't bad decisions given the information they had at the time, but proper usage style has shifted since then, and as a result there are a lot of embarassments in the standard library. That doesn't mean that it's a bad idea to use the STL; the embarassments are generally of the aesthetic rather than functional variety, and the fact that it's standardized counts for a lot more than the embarassments. But it does mean that it's generally a bad idea to look to the Standard Library for guidance on what good C++ looks like or acts like.

#12 yahastu   Members   -  Reputation: 152

Like
0Likes
Like

Posted 17 November 2007 - 10:29 AM

Quote:
Original post by Sneftel
There is one gigantic difference: inner classes can access private class members. That means that an inner class can communicate with its outer class without having to go through the outer class' public interface. Because of this, making a class an inner class should be thought of as increasing the size of the class (a bad thing) while complicating its responsibilities (also a bad thing). Because of this, a class should be an inner class ONLY where it cannot reasonably be implemented using the outer class' public interface.


I doubt that an inner class actually increases the compiled size of the outer class instances, so if by "size" you refer to complexity, then you complexity of a nested class combination is really not greater than the complexity of the 2 classes separately...so I do not see any merit to your statement that "it is bad."

It does not complicate the responsibilities, it just groups those common responsibilities into the same place so that they are less likely to make an error...you're just suggesting that logically connected code should be made completely separate? Isn't that what is called "spaghetti" ? How is that good?

Often times I use an internal node struct (or similar) that I do not want the user of the class to see or instantiate directly. Hiding it inside the base class works perfectly, and is no more complicated at all. Yes I do see it as "part" of the class...because it really IS part of the class, and thats the way it should be! There is no "generic node" and I cant think of any advantage to declaring a million ungrouped "X_node" and "Y_node" in public scope.



#13 iMalc   Crossbones+   -  Reputation: 2314

Like
0Likes
Like

Posted 17 November 2007 - 02:16 PM

It sounds like you're trying to decide when composition is the right thing to use. You use it when one thing is composed of other things.

Or are you talking about placing the sub-object class definition inside the definition of the class that uses it? If so, that something that might be good for data hiding, but you can run into trouble with it if your compiler is a little old.

#14 jhq   Members   -  Reputation: 133

Like
0Likes
Like

Posted 17 November 2007 - 05:49 PM

Quote:
Original post by iMalc
Or are you talking about placing the sub-object class definition inside the definition of the class that uses it?

I do mean this. What else can I refer to? :)


Quote:
Original post by yahastu
It does not complicate the responsibilities, it just groups those common responsibilities into the same place so that they are less likely to make an error...you're just suggesting that logically connected code should be made completely separate? Isn't that what is called "spaghetti" ? How is that good?

Often times I use an internal node struct (or similar) that I do not want the user of the class to see or instantiate directly. Hiding it inside the base class works perfectly, and is no more complicated at all. Yes I do see it as "part" of the class...because it really IS part of the class, and thats the way it should be! There is no "generic node" and I cant think of any advantage to declaring a million ungrouped "X_node" and "Y_node" in public scope.

I do agree with you. I think nested definition is a perfect mechanism provided by cpp that you personally want to express the ideal that something won't logically make much sense if it was used by others except its outer class.


#15 Sneftel   Senior Moderators   -  Reputation: 1781

Like
0Likes
Like

Posted 17 November 2007 - 08:47 PM

Quote:
Original post by yahastu
Quote:
Original post by Sneftel
There is one gigantic difference: inner classes can access private class members. That means that an inner class can communicate with its outer class without having to go through the outer class' public interface. Because of this, making a class an inner class should be thought of as increasing the size of the class (a bad thing) while complicating its responsibilities (also a bad thing). Because of this, a class should be an inner class ONLY where it cannot reasonably be implemented using the outer class' public interface.

I doubt that an inner class actually increases the compiled size of the outer class instances, so if by "size" you refer to complexity, then you complexity of a nested class combination is really not greater than the complexity of the 2 classes separately...so I do not see any merit to your statement that "it is bad."
By size I refer to the length of the source code. For code which does not significantly segregate responsiblities, the difficulty of maintaining the code tends to grow quadratically with size, so it's important. Separating the classes provides that segregation.
Quote:
Often times I use an internal node struct (or similar) that I do not want the user of the class to see or instantiate directly.

Consider: Do you want your AI code to see your texture-related classes? If not, how do you prevent them from doing so?

#16 daniel battaglia   Members   -  Reputation: 122

Like
0Likes
Like

Posted 24 November 2007 - 06:40 AM

first time poster here...

what i use nested classes for, mainly, is to impliment a base/interface class. i have a factory class that contains the implimentations for a public base class, and methods of the factory return derived objects (the nested classes) as base class pointers (pretty basic stuff).

nested enums and C Structs to me are used for either scoping in the class namespace, or for structs i often use them to wrap up data for internal arguments passing. im currently working on a C++ wrapper library for a C library (portmidi, to be more specific), and im using everything i mentioned above to help in hiding the user un-friendly C interface behind a more modern C++ interface.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS