4

Voici un exemple d'héritage multiple. J'ai utilisé l'opérateur de résolution d'étendue pour résoudre l'ambiguïté au lieu d'une classe virtuelle.Éviter l'ambiguïté induite par héritage multiple en utilisant la résolution de portée

struct A 
{ 
    int i; 
}; 

struct B : A 
{}; 

struct C : A 
{}; 

struct D: B, C 
{ 
    void f() 
    { 
     B::i = 10; 
    } 
    void g() 
    { 
     std::cout << B::i <<std::endl; 
    } 
}; 

int main() 
{ 
    D d1; 
    d1.f(); 
    d1.g(); 
    return 0; 
} 

Est-ce que B::i est bien formé?

+0

Ou ne pas déranger avec l'héritage multiple en premier lieu. – Ron

+3

@Ron - Parfois, tu dois faire ce que tu dois faire. – StoryTeller

Répondre

5

Est-ce que B::i est bien formé?

Oui, c'est. La plus référence pertinente est [class.qual]/1:

Si le emboîtées nom spécificateur d'un id qualifié désigne une classe, le nom spécifié après le nom spécificateur imbriquée est recherché dans le champ de la classe , sauf pour les cas énumérés ci-dessous. Le nom doit représenter un ou plusieurs membres de cette classe ou de l'une de ses classes de base .

Ce qui vous pouvez nommer i spécifie le compte de celui-ci étant un membre de la base de B. L'accessibilité est seulement vérifiée après, et dans votre cas c'est public.

[class.access.base]/5

... L'accès à un membre est affecté par la classe dans laquelle le membre est nommé. Cette classe de dénomination est la classe dans laquelle le membre nom a regardé et a trouvé ... Un m membre est accessible au point R lorsque nommé en classe N si

  • il existe une classe de base B de N accessible à R, et m accessible à R lorsqu'il est nommé dans la classe B.
1

Oui. Ceux-ci sont extrait du C++ règles de grammaire standards:

id-expression: 
    unqualified-id 
    qualified-id 

postfix-expression: 
    [...] 
    postfix-expression . template[opt] id-expression 
    [...] 

Dans [class.mcft.non-statique]:

Lorsqu'un id-expression (8.1) qui ne fait pas partie d'un membre de la classe syntaxe d'accès (8.2.5) et non utilisé pour former un pointeur vers le membre (8.3.1) est utilisé dans un membre de la classe X dans un contexte où cela peut être utilisé (8.1.2), si recherche de nom (6.4) résout le nom dans l'id-expression en un membre non-statique non-type d'une classe C, et si soit l'expression id est potentiellement évaluée, soit C est X ou une classe de base de X, l'expression id est transformé en une expression d'accès de membre de classe (8.2.5) en utilisant (* this) (12.2.2.1) en tant qu'expression postfixe à gauche de la. opérateur.