Je suis l'aide de shared_ptr et STL largement dans un projet, et cela conduit à de trop longues, le risque d'erreur de types comme shared_ptr< vector< shared_ptr > > (je suis un ObjC programmeur de préférence, où les noms longs sont la norme, et encore c'est beaucoup trop.) Il serait beaucoup plus clair, je crois, à l'appel de cette FooListPtr et la documentation de la convention de nommage "Ptr" signifie shared_ptr et "Liste", vecteur de shared_ptr.
pour commencer, je vous recommande d'utiliser une bonne conception des structures pour la détermination de la portée (par exemple, les espaces de noms) ainsi que les descriptifs, le non-abrégée des noms pour les typedefs. FooListPtr
est terriblement court, de l'omi. personne ne veut de deviner ce qu'est une abréviation qui signifie (ou être surpris de trouver des Foo est const, partagées, etc.), et personne ne veut de modifier leur code, simplement en raison de la portée des collisions.
il peut également aider à choisir un préfixe pour les typedefs dans vos bibliothèques (ainsi que d'autres catégories communes).
c'est aussi une mauvaise idée de faire glisser les types de leurs déclaré portée:
namespace MON {
namespace Diddy {
class Foo;
} /* << Diddy */
/*...*/
typedef Diddy::Foo Diddy_Foo;
} /* << MON */
il y a des exceptions à cela:
- un tout ecapsualted type privé
- un type au sein d'une nouvelle portée
pendant que nous y sommes, using
en l'espace de noms d'étendues et de l'espace de noms d'alias doit être évitée - qualifier le champ si vous souhaitez à l'avenir pour réduire maintentance.
C'est facile de typedef, mais elle provoque des maux de tête avec les en-têtes. Il me semble avoir plusieurs options d'où pour définir FooListPtr:
Foo.h. Qui entrelace tous les en-têtes et crée de graves problèmes de compilation, c'est donc un non-starter.
il peut être une option pour les déclarations qui dépendent d'autres déclarations. ce qui implique que vous avez besoin de diviser les paquets, ou qu'il y est une commune localisée d'interface pour les sous-systèmes.
FooFwd.h ("forward-tête"). C'est ce Efficace C++ indique, basé sur iosfwd.h. C'est très cohérent, mais la surcharge de maintien de deux fois le nombre d'en-têtes semble ennuyeux au possible.
ne vous inquiétez pas à propos de la maintenance de cela, vraiment. c'est une bonne pratique. le compilateur utilise avant les déclarations et les typedefs avec très peu d'effort. ce n'est pas gênant car il permet de réduire vos dépendances, et permet de s'assurer qu'ils sont tous corrects et visible. il n'y a vraiment pas plus à maintenir puisque les autres fichiers, reportez-vous à 'l'ensemble des types d'en-tête".
Commun.h (mettre tous ensemble dans un seul fichier). Cela tue la réutilisabilité en enlacent beaucoup de sans rapport avec les types. Maintenant, vous ne pouvez pas juste prendre un objet et le déplacer vers un autre projet. C'est un non-starter.
en fonction des dépendances d'inclusions sont excellents (idéal, vraiment) - ne pas négliger. vous devez évidemment avoir pour créer un package d'interfaces (ou bibliothèques) qui sont conçus et bien structuré, et de représenter les classes connexes de composants. vous êtes en rendant inutile question de l'objet/la réutilisation des composants. minimiser la statique des données d'une bibliothèque, et de laisser le lien et la bande phases de faire leur travail. encore une fois, gardez vos paquets petits et réutilisables, et ce ne sera pas un problème (en supposant que vos bibliothèques/packages sont bien conçus).
Une sorte de fantaisie #define magie qui typedef s'il n'a pas déjà été typedefed. J'ai un respectueux de l'aversion pour le préprocesseur parce que je pense qu'il rend difficile pour les nouvelles personnes pour analyser le code, mais peut-être que....
en fait, vous pouvez déclarer un typedef dans le même champ d'application plusieurs fois (par exemple, dans deux en-têtes) - qui n'est pas une erreur.
déclarer un typedef dans le même champ d'application avec différents types de sous-jacents est une erreur. évidemment. vous devez éviter cela, et heureusement, le compilateur impose.
pour éviter cela, créer une "traduction construire" qui comprend le monde - le compilateur signalera les déclarations de typedeffed types qui ne correspondent pas.
en essayant de se faufiler par avec un minimum de typedefs et/ou vers l'avant (qui sont assez proches pour gratuit lors de la compilation) ne vaut pas l'effort. parfois, vous aurez besoin d'un tas de soutien conditionnel de déclaration - une fois défini, il est facile stl (bibliothèques sont un bon exemple de cela-dans le cas où vous êtes également en avant en déclarant template<typename,typename>class vector;
).
il est préférable d'avoir toutes ces déclarations visible pour intercepter les erreurs immédiatement, et vous pouvez éviter le préprocesseur dans ce cas comme un bonus.
L'utilisation d'un vecteur sous-classe plutôt qu'à une définition de type. Cela semble dangereux...
une sous-classe de std::vector
est souvent signalé comme une "erreur de débutant". ce conteneur n'était pas censé être sous-classé. n'ayez pas recours à des mauvaises pratiques simplement de réduire les temps de compilation/dépendances. si la dépendance est vraiment important, vous devriez probablement utiliser des PIMPL, de toute façon:
// <package>.types.hpp
namespace MON {
class FooListPtr;
}
// FooListPtr.hpp
namespace MON {
class FooListPtr {
/* ... */
private:
shared_ptr< vector< shared_ptr<const Foo> > > d_data;
};
}
Sont là les meilleures pratiques ici? Comment peuvent-ils transformer en véritable code, lorsque la réutilisabilité, la lisibilité et la cohérence sont d'une importance primordiale?
en fin de compte, j'ai trouvé une petite concis paquet approche fondée sur le meilleur, pour les réutiliser, réduire les temps de compilation, et en réduisant la dépendance.