2011-07-07 3 views
7

Je trouve que faire une classe non-copiable m'aide beaucoup avec la qualité de mon code. Initialement, je l'ai fait avec boost :: nononcopyable, mais j'ai trouvé que les erreurs du compilateur VC++ ne sont pas aussi utiles qu'avec les membres privés (un double clic mène au mauvais endroit dans le code). En effet, il m'a alerté dans un certain nombre de cas où les classes n'ont pas été transmises comme référence où elles devraient l'être. Tant et si bien, que j'aimerais beaucoup recevoir un avertissement même sur les classes que j'ai juste besoin de copier construire une fois.C++ Non copiable sauf parfois

Existe-t-il un bon moyen de le faire? Je pensais par exemple à laisser au-dessus de deux méthodes privées et à ajouter un constructeur public T (T const &, bool dummy) pour appeler quand je veux vraiment copier construct. Ou peut-être faire alternativement au-dessus de deux méthodes publiques et en quelque sorte activer un avertissement du compilateur lors de la construction de la copie, en supprimant l'avertissement où je veux.

Ou peut-être y a-t-il un meilleur ensemble?

Répondre

6

Vous ne savez pas exactement ce que vous voulez, mais si vous marquez le constructeur de copie explicit, la classe ne peut pas être transmise par valeur ou initialisée par copie, mais vous pouvez copier-construire en utilisant l'initialisation directe.

Vous voudriez probablement garder l'opérateur d'affectation privé, peut-être qu'une base NonAssignable serait utile pour cela.

+1

J'aime cette réponse mieux. Le problème avec les constructeurs de copie, d'après mon expérience, est quand ils sont invoqués "par accident" sur un objet énorme. 'explicit 'vous force à y penser quand vous les invoquez, ce qui devrait être suffisant. – Nemo

+0

Salut, cela convient parfaitement à mes besoins. Merci. – Cookie

2

Je pense que vous avez nommé un chemin parfait là-bas.

Je me souvenais juste un pur petit truc que j'ai joué dans une autre base de code que je travaillais sur (?):

struct T 
{ 
    friend class SomeClientThatCanConstructT; 
    T(T const&); 

    private: 
    T(T const&);   
}; 

Comme il est indiqué dans les commentaires ci-après ne voleront pas

Vous pouvez opter pour un nom explicite (comme CopyConstruct) et compter sur RVO pour être tout aussi efficace:

struct T 
{ 
    inline T CopyConstruct() const  { return *this; } 
    inline T& AssignTo(T& dst) const { return dst = *this; } 
    inline T& AssignFrom(const T& src) { return *this = src; } 

    private: 
    T(T const&); 
    T& operator=(T const&); 
}; 

+0

J'ai réfléchi à cela mais votre 'CopyConstruct' nécessite que le constructeur de copie soit accessible même si le compilateur ne l'appelle pas. –

+0

Shute. Merci de me le rappeler. C'est en effet un bouchon. Bien sûr, vous pouvez l'améliorer tout le long, mais pour l'appel du constructeur, il n'y a vraiment pas d'alternative à votre solution 'tag parameter'. Quand j'y pense, je me souviens tout à coup de l'avoir fait moi-même ...Mise à jour de la réponse – sehe

+0

Ce petit ami semble faire l'affaire maintenant. –

0

Vous pourriez construire un défaut T puis ajouter une méthode assign à utiliser. Cependant, cela ne semble pas optimal, indiquant que vous pourriez vouloir revoir vos besoins de copie.

0

Je n'aime pas l'idée de restreindre un type (CopyConstructible est un concept très utilisé dans tout le stdlib) car il pourrait être mal utilisé. Si vous pouvez construire un objet à partir d'une autre instance, il devrait être copiable. Il détourne également le lecteur du code important sans servir de véritable but.

Peut-être qu'un avertissement ou une assertion en mode débogage déclenché par le constructeur de la copie est vraiment ce que vous cherchez?

+0

Y a-t-il une telle chose? par exemple. puis-je définir un avertissement défini par l'utilisateur chaque fois que le compilateur ou l'éditeur de liens est lié à une fonction? puis supprimer l'avertissement dans le fichier objet que je veux? Comme un avertissement pragma désactiver? – Cookie

Questions connexes