Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 722
Rob Avatar asked Oct 19 '08 18:10

Rob


2 Answers

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.

like image 115
paercebal Avatar answered Sep 23 '22 18:09

paercebal


One con that can become a big deal for large projects is that it is impossible to make a forward declaration for nested classes or enums.

like image 40
Adam Rosenfield Avatar answered Sep 20 '22 18:09

Adam Rosenfield