Pros and cons of using nested C++ classes and enumerations?
c++, class, enums, nested
Solution
Nested classes
There are several side effects to classes nested inside classes that I usually consider flaws (if not pure antipatterns).
Let's 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:
- Privilegied Access: A::B has privilegied access to all members of A (methods, variables, symbols, etc.), which weakens encapsulation
- A's scope is candidate for symbol lookup: code from inside B will see all symbols from A as possible candidates for a symbol lookup, which can confuse the code
- forward-declaration: There is no way to forward-declare A::B without giving a full declaration of A
- Extensibility: It is impossible to add another class A::C unless you are owner of A
- Code verbosity: putting classes into classes only makes headers larger. You can still separate this into multiple declarations, but there's no way to use namespace-like aliases, imports or usings.
As a conclusion, unless exceptions (e.g. the nested class is an intimate part of the nesting class... And even then...), I see no point in nested classes in normal code, as the flaws outweights by magnitudes the perceived advantages.
Furthermore, it smells as a clumsy attempt to simulate namespacing without using C++ namespaces.
On the pro-side, you isolate this code, and if private, make it unusable but from the "outside" class...
Nested enums
Pros: Everything.
Con: Nothing.
The fact is enum items 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 by putting each enum in a different namespace/class will enable 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 defined the class enum:
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 problems.
Problem
What are the pros and cons of using nested public C++ classes and enumerations? For example, suppose you have a class called `printer`, and this class also stores information on output trays, you could have: ``` class printer { public: std::string name_; enum TYPE { TYPE_LOCAL, TYPE_NETWORK, }; class output_tray { ... }; ... }; printer prn; printer::TYPE type; printer::output_tray tray; ``` Alternatively: ``` 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 can see the benefits of nesting private enums/classes, but when it comes to public ones, the office is split - it seems to be more of a style choice. So, which do you prefer and why?