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

前端 未结 13 2170
悲&欢浪女
悲&欢浪女 2020-11-29 23:43

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 store

13条回答
  •  醉梦人生
    2020-11-30 00:11

    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.

提交回复
热议问题