J'aimerais créer une classe associée à une autre classe dans une sorte de relation parent-enfant. Pour cela, la classe "enfant" a besoin d'une référence à son parent.
Par exemple: P>
template <typename T> class TEvent { private: T* Owner; public: TEvent(T* parent) : Owner(parent) {} }; class Foo { private: TEvent<Foo> Froozle; // see below };
5 Réponses :
Il est correct d'utiliser ceci code> dans la liste d'initialisation, tant qu'il n'est pas utilisé pour accéder à des membres qui n'ont pas encore été initialisés. P>
Ce qu'il dit. Tant que les objets que vous passez ceci code> sur "savoir" ne pas la toucher au cours de leur construction (car l'objet
Ce code> fait référence n'est pas entièrement construit à ce moment), Cela va bien, même si certains compilateurs (notamment VC) émettent un avertissement pour cela.
VC ++ est le point clé ici. Ça marche en effet. On dirait que je dois supprimer la "erreur" de force. Merci beaucoup!
Je souhaite que VC ++ n'en émet qu'un avertissement lorsque le membre de "Ceci" à l'intérieur de la CTOR a accédé. BTW, Google :: LogMessage Class dans Google-Glog stocke "Ceci" à elle-même Liste des Mem-Initizer de CTOR à la fin du débogage. Je devais recompiler avec l'avertissement #pragma (4355: désactivé) pour le faire fonctionner dans VC2010.
Ceci est censé travailler; En fait,
template<class T> class Child { private: T *parent; public: Child(T *parent) : parent(parent) {} }; class Parent { private: Child<Parent> child; public: Parent() : child(this) {} };
Le drapeau "Treat Warnings comme des erreurs" Drapeau de la VC et de l'en-tête de documentation MSDN indiquant "Message d'erreur". :) Vous avez absolument raison - ça marche, je ne l'ai tout simplement pas vu. Merci beaucoup!
de la norme 12.6.2 / 7 "Initialisation des bases et des membres" (emphase des miennes):
noms dans la liste d'expression d'un Les initialiseurs de Mem sont évalués dans le portée du constructeur pour lequel le L'initialiseur de Mem est spécifié. p>
[Exemple: P>
class X { int a; int b; int i; int j; public: const int& r; X(int i): r(a), b(i), i(i), j(this->i) {} };
Cela signifie-t-il que "ceci" est uniquement autorisé dans la liste de CTors de Mem-Initialiseur ou est-il également autorisé dans le corps de la CTOR? J'ai essayé d'utiliser "ceci" à l'intérieur du corps de CTor en VC2010 ++ plusieurs fois et tout cela compile et fonctionne bien avec un avertissement C4355 désactivé mais simplement parce que cela fonctionne ne signifie pas que je suis autorisé à être autorisé. Jusqu'à présent, je n'ai trouvé aucun dans le DOC Open-Standard qui indique s'il est autorisé à se référer à "Ceci" à l'intérieur du corps de CTOR ou non.
@Davidlee: à l'intérieur du constructeur, Ce code> pointe sur l'objet en cours de construction (comme dans la liste d'initialistes comme décrit ci-dessus). Vous pouvez définitivement utiliser
ce code> à l'intérieur du corps du constructeur.
Si vous souhaitez supprimer l'avertissement, faites-le simplement:
class Foo { public: Foo() : Froozle(get_this()) {} private: Foo* get_this() { return this; } TEvent<Foo> Froozle; // see below };
Il h. Pourquoi une méthode appelle-t-elle d'accord, mais une référence directe n'est-elle pas? Compilateur idiot :)
Je ne pense pas que cela vous échoue, à moins que vous n'ayez le niveau d'avertissement réglé sur 4 (ou similaire, je suppose Visual Studio) et j'ai activé "Traitement des avertissements comme des erreurs".
Fondamentalement, cet avertissement est un Bonne chose, puisqu'il ne vous laissera pas accidentellement utiliser em> le pointeur code> ce bouton code> lorsque ce qu'il pointe est encore à construire. P> Cependant, quand Vous savez ce que vous faites partout où Vous pouvez en débarrasser (à nouveau, en supposant que Visual Studio) en décorant le constructeur (sauf s'il est défini dans la déclaration de classe - vous devez décorer toute la classe): P> ce code> est transmis dans la liste d'initialisation, l'avertissement et l'erreur causés par cela seront ennuyeux. P>
// warning C4355: 'this' : used in base member initializer list
#pragma warning (push)
#pragma warning (disable : 4355)
some_class::some_class()
: ...
{
}
#pragma warning (pop)