2014-09-08 1 views
5

Je suis curieux quant au comportement des éléments suivants:Appel fonction virtuelle du constructeur membre

#include <iostream> 
#include <string> 
struct A; 
struct B { 
    std::string b; 
    B(A& a); 
}; 
struct A { 
    B member; 
    virtual std::string f() { return "Hello, World!"; } 
    A() : member(*this) {} 
}; 
B::B(A& a) : b(a.f()) {} 
int main() { 
    std::cout << A().member.b; 
} 

Est-ce nécessaire d'imprimer le résultat attendu? Ou est-ce un comportement indéfini?

Répondre

6

Ceci est légal. § 12.7 [class.cdtor]/p4:

fonctions membres, y compris des fonctions virtuelles (10.3), peuvent être appelés pendant la construction ou la destruction (12.6.2). Lorsqu'une fonction virtuelle est appelée directement ou indirectement par un constructeur ou par un destructeur , y compris lors de la construction ou de la destruction des membres de données non statiques de la classe , l'objet auquel s'applique l'appel est l'objet (appelez-le x) en cours de construction ou de destruction, la fonction appelée est le remplaçant final dans la classe du destructeur du constructeur ou et pas un remplaçant dans une classe plus dérivée. Si l'appel de fonction virtuelle utilise un accès explicite membre de classe (5.2.5) et l'expression de l'objet fait référence à l'objet complet de x ou l'un des sous-objets de la classe de base de cet objet, mais pas x ou l'un des ses sous-objets de classe de base, le comportement est indéfini.

Le cas UB ne s'applique pas ici.

+0

Je ne comprends jamais bien ... pourquoi ça ne s'applique pas? 'a.f()' devrait se référer à l'objet complet de x. Est-ce que je le lis mal? –

+0

@MarcoA. UB ne se produit que s'il fait référence à l'objet complet de 'x' ou à l'un des sous-objets de classe de base ** de cet objet, mais pas' x' ou à l'un de ses sous-objets de classe de base **. Dans ce cas, l'objet pertinent en construction est un 'A', et l'expression de l'objet fait référence à l'objet en construction, donc le comportement est bien défini. –

+0

Merci de m'avoir aidé: 'Un objet qui n'est pas un sous-objet d'un autre objet est appelé un objet complet. '' Donc, n'est-ce pas 'a' référence à un objet complet ici? –

Questions connexes