Classes imbriquées
Il ya plusieurs effets secondaires des classes imbriquées à l'intérieur des classes que j'ai l'habitude de considérer les défauts (si ce n'est de la pure antipatterns).
Imaginons le code suivant :
class A
{
public :
class B { /* etc. */ } ;
// etc.
} ;
Ou encore:
class A
{
public :
class B ;
// etc.
} ;
class A::B
{
public :
// etc.
} ;
Donc:
-
Privilégiées d'Accès: A::B a privilégiées d'accès à tous les membres d'Une (méthodes, les variables, les symboles, etc.), ce qui affaiblit l'encapsulation
-
Un champ est candidat à la recherche de symbole: code de l'intérieur de B voir tous les symboles à partir d'Une comme des candidats possibles pour une recherche de symbole, qui peut confondre le code
-
l'avant-déclaration: Il n'y a aucun moyen de l'avant-déclarer Un::B sans donner l'intégralité de la déclaration d'Un
-
Extensibilité: Il est impossible d'ajouter une autre classe A::C, sauf si vous êtes propriétaire d'Un
-
Code de verbosité: mettre les classes en classes rend seulement les en-têtes de plus. Vous pouvez toujours séparés en plusieurs déclarations, mais il n'y a pas moyen d'utiliser l'espace de noms comme alias, les importations ou de l'usage.
En conclusion, sauf exceptions (par exemple, la classe imbriquée est une partie intime de l'imbrication de la classe... Et puis même...), je ne vois pas en classes imbriquées dans le code, comme les lacunes outweights par les magnitudes les avantages perçus.
En outre, il sent comme une tentative maladroite pour simuler namespacing sans l'aide de C++ espaces de noms.
Sur le pro-côté, vous isoler de ce code, et si privé, de le rendre inutilisable, mais de "l'extérieur" de la classe...
Imbriqués les énumérations
Avantages: Tout.
Con: Rien.
Le fait est enum éléments vont polluer la portée mondiale:
// collision
enum Value { empty = 7, undefined, defined } ;
enum Glass { empty = 42, half, full } ;
// empty is from Value or Glass?
Ony en mettant chaque enum dans un espace de noms différent/classe vous permettra d'éviter cette 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 ;
A noter que C++0x défini la classe enum:
enum class Value { empty, undefined, defined } ;
enum class Glass { empty, half, full } ;
// Value e = Value::empty ;
// Glass f = Glass::empty ;
exactement pour ce genre de problèmes.