Pros and cons of using nested C ++ classes and enums?

What are the pros and cons of using nested C ++ public classes and enums? For example, suppose you have a class called printer , and this class also stores information about output trays, you could:

 class printer { public: std::string name_; enum TYPE { TYPE_LOCAL, TYPE_NETWORK, }; class output_tray { ... }; ... }; printer prn; printer::TYPE type; printer::output_tray tray; 

As an alternative:

 class printer { public: std::string name_; ... }; enum PRINTER_TYPE { PRINTER_TYPE_LOCAL, PRINTER_TYPE_NETWORK, }; class output_tray { ... }; printer prn; PRINTER_TYPE type; output_tray tray; 

I see the benefits of nesting private enums / classes, but when it comes to public, the office is split up - it seems it's more a style choice.

So what do you prefer and why?

+42
c ++ enums class nested
Oct 19 '08 at 18:05
source share
13 answers

Nested Classes

There are several side effects to classes nested inside classes, which I usually see as flaws (if not pure antipatterns).

Imagine the following code:

 class A { public : class B { /* etc. */ } ; // etc. } ; 

Or even:

 class A { public : class B ; // etc. } ; class A::B { public : // etc. } ; 

So:

  • Privileged Access: A :: B has privileged access to all members of A (methods, variables, characters, etc.), which weakens encapsulation
  • The area is a candidate for finding a character: the code inside B will see the characters all from A as possible candidates for finding a character, which may confuse the code
  • forward-declaration: You cannot forward A :: B without giving a full declaration to A
  • Extensibility: It is not possible to add another class A :: C unless you own A
  • Verbose code: placing classes in classes only increases the size of the headers. You can still split this into multiple declarations, but there is no way to use aliases, import, or use names like a namespace.

As a conclusion, if there are exceptions (for example, a nested class is an intimate part of a nesting class ... And even then ...), I donโ€™t see the point in nested classes in normal code, since the disadvantages of the advantages are perceived advantages.

Also, it smells like a clumsy attempt to mimic a namespace without using C ++ namespaces.

On the pro side, you isolate this code and, if it is closed, make it unusable, but from the class "outside" ...

Enclosed Transfers

Pros: everything.

Con: Nothing.

The fact that listing elements will pollute the global scope:

 // collision enum Value { empty = 7, undefined, defined } ; enum Glass { empty = 42, half, full } ; // empty is from Value or Glass? 

Ony, placing each enumeration in a different namespace / class will allow you to avoid this collision:

 namespace Value { enum type { empty = 7, undefined, defined } ; } namespace Glass { enum type { empty = 42, half, full } ; } // Value::type e = Value::empty ; // Glass::type f = Glass::empty ; 

Note that C ++ 0x defines a class enumeration:

 enum class Value { empty, undefined, defined } ; enum class Glass { empty, half, full } ; // Value e = Value::empty ; // Glass f = Glass::empty ; 

exactly for this kind of problem.

+38
Oct 19 '08 at 18:15
source share

One conflict that can be a big deal for large projects is that it is not possible to make a declaration for nested classes or enumerations.

+6
Oct 19 '08 at 18:10
source share

If you will never use the dependent class for anything other than working with independent class implementations, nested classes are fine in my opinion.

This is when you want to use the "inner" class as a standalone object that can start to become a little manky, and you should start writing extractor / insert procedures. Not a good situation.

+2
Oct. 19 '08 at 18:15
source share

It looks like you should use namespaces instead of classes to group together, like things that are related to each other in this way. One of the codes that I could see when executing the nested classes is that you have a really large source file that is hard to find when you are looking for a section.

+2
Oct 19 '08 at 18:21
source share

There are no pros and cons when using nested C ++ public classes. There are only facts. These facts are approved by the C ++ standard. Regardless of whether the fact depends on the nested C ++ public classes like pro or con, it depends on the specific problem you are trying to solve. The example you provided does not allow us to judge whether nested classes are suitable or not.

One fact about nested classes is that they have privileged access to all members of the class to which they belong. This is con if the nested classes do not need such access. But if a nested class does not need such access, it should not be declared as a nested class. There are situations when class A wants to provide privileged access to some other classes of B. There are three solutions to this problem.

  • Make B a friend A
  • Make B a nested class A
  • Create the methods and attributes that B needs, public members of A.

In this situation, he # 3 violates encapsulation because A has control over his friends and his nested classes, but not over classes that call him public methods or gain access to his public attributes.

Another fact about nested classes is that it is not possible to add another class A :: C as a nested class A unless you are the owner of A. However, this is perfectly reasonable because nested classes have privileged access. If it were possible to add A :: C as a nested class of A, then A :: C could trick A into providing access to privileged information; and that you break encapsulation. It is basically the same as with the friend declaration: the friend declaration does not provide you with any special privileges that your friend hides from others; This allows your friends to receive information that you hide from your friends. In C ++, calling someone else an altruistic act, rather than selfish. The same is true for a class to be a nested class.

Som other facts about nested public classes:

  • The area is a candidate for finding the character B. If you do not want this, make B a friend of A instead of a nested class. However, there are times when you want exactly this kind of character search.
  • A :: B cannot be declared forward : A and A :: B are closely related. The ability to use A :: B without knowing A will only hide this fact.

To summarize this: if the tool does not meet your needs, do not blame the tool; blame yourself for using the tool; others may have different problems for which the tool is perfect.

+2
Aug 31 '13 at 21:24
source share

paercebal said everything I would say about nested enumerations.

Nested WRT classes, my common and almost the only use case for them, is when I have a class that controls a particular type of resource, and I need a data class that represents something specific for that resource. In your case, output_tray may be a good example, but usually I donโ€™t use nested classes if the class will have any methods that will be called because of the class that contains the class, or it is more than the data class first of all. Usually, I also do not insert data classes unless the contained class never refers directly to the containing class.

So, for example, if I had a printer_manipulator class, it could contain a class for printer manipulation errors, but the printer itself would be a class not contained in the class.

Hope this helps. :)

+1
Oct 19 '08 at 20:39
source share

Remember that you can always push a nested class to a higher level later, but you cannot do the opposite without breaking existing code. Therefore, my advice should first make it a nested class, and if it starts to become a problem, make it a top-level class in the next version.

+1
Mar 28 '14 at 17:05
source share

For me, the big conflict is that it becomes part of the global namespace. If an enumeration or related class really only applies to the class it is in, then that makes sense. Thus, in the printer, everything that includes the printer will know that there is full access to enum PRINTER_TYPE, where it really does not need to be known about it. I canโ€™t say that I have ever used an inner class, but for listing it seems more logical to keep it inside. As another poster noted, itโ€™s also nice to use namespaces to group similar elements, since clogging up the global namespace can really be bad. I previously worked on large projects, and it only takes 20 minutes to create a complete complete list in the global namespace. In my opinion, nested enums and namespaced classes / structs are probably the cleanest approach.

0
Oct 19 '08 at 19:13
source share

I agree with the messages protecting the embedding of your enum in the class, but there are times when it makes sense not to do this (but please at least put it in the namespace). If several classes use an enumeration defined in another class, then these classes directly depend on this other specific class (to which the enumeration belongs). This, of course, represents a design flaw, as this class will be responsible for this enumeration, as well as for other responsibilities.

So yes, insert enum into the class if other code uses only this enumeration to interact directly with this particular class. Otherwise, find the best place to store the enum, such as a namespace.

0
Oct. 20 '08 at 4:35
source share

If you put enum in a class or namespace, intellisense will be able to give you directions when you try to remember enumeration names. A little thing for sure, but sometimes the little things matter.

0
Oct 20 '08 at 4:54
source share

Visual Studio 2008, it seems, cannot provide intellisense for nested classes, so I switched to the PIMPL idiom in most cases when I had a nested class. I always put enumerations in a class if it is used only by this class or outside the class in the same namespace as the class when more than one class uses an enumeration.

0
Oct 20 '08 at 18:15
source share

I see con for nested classes that it is better to use general programming.

If a small class is defined outside the large, you can make the large class a class template and use any โ€œsmallโ€ class that you may need in the future with the large class.

General programming is a powerful tool, and IMHO, we must keep this in mind when developing extensible programs. It is strange that no one mentioned this.

0
Sep 11 '13 at
source share

The only problem with nested classes that I came across was that C ++ does not allow you to reference the object of the enclosing class in the nested functions of the class. We cannot say "Enclosing :: this"

(But maybe there is a way?)

-one
May 31 '13 at 10:37
source share



All Articles