2011-06-27 12 views
7
class A { 
    public: 
     void fa() { 
     } 
    }; 

class B : public A{ 
public: 
    void fb() { 
    } 
}; 

class C : public A, public B { 
public: 
    void fc() { 
     //call A::fa(), not B::A::fa(); 
    } 
}; 

Cómo llamar al A::fa() desde la función C::fc().Consulte los miembros de la clase base de la clase derivada

GCC advierte con direct base A inaccessible in C due to ambiguity, ¿significa esto que no hay una forma directa de referirse a los miembros de la clase base?

+0

En su código actual clase 'B' no hereda' A' clase. Ha puesto el código actualizado? – iammilind

+0

Mi error :) , ahora está fijado – MKo

+1

¿Quieres que haya un subobjeto de clase base 'A' para' C' o dos subobjetos de clase base 'A' (uno de' C' que deriva de 'A'' y otro de' B' que deriva de 'A')? Ahora mismo tienes dos, que pueden o no ser tu intención. –

Respuesta

0

Puede utilizar virtual herencia para superar tal problema:

class B : virtual public A { 

Ahora, puede utilizar A::fa() simplemente en el niño class C.

void fc() 
{ 
    fa(); 
} 

Sin embargo, por lo general no veo ninguna necesidad práctica para heredar class A nuevo en class C, cuando ya es Bpublic aliado heredar A. Así, en su caso, puede que sea sencillo:

class C : public B { 

Editar:

Si quieres 2 casos para A. a continuación, la instancia directa que tiene la intención se puede hacer como un objeto de C:

class C : public B { 
    A obj; 

Porque, que tiene una directamente heredado A no se podrá utilizar en cualquier caso. No puede declarar ningún puntero o referencia dentro del alcance de C.

+0

Esto no es para uso práctico, solo quiero saber si hay alguna manera de hacerlo. Por cierto, en el caso de la herencia virtual, habrá una clase base A, y no habrá ambigüedades. – MKo

+0

@MKo, ya he mencionado en mi respuesta editada. Para su caso, no necesita heredar 'A 'en' C'. También podría ser un mal diseño a largo plazo. – iammilind

1

que acaba de compilar código en que codepad.org, poniendo A::fa() es suficiente para llamar la FA() de su función C::fc().

void fc() { 
     A::fa(); 
    } 

El siguiente es el enlace al teclado con su código.

http://codepad.org/NMFTFRnt

+0

No sé qué código de compilación utiliza, pero clang 3.0/133044 y g ++ 4.5.1 rechazan eso. –

+0

@James McNellis: sí, está más relacionado con el ** problema del compilador ** no con el lenguaje en sí. – Jhaliya

+0

Compila porque 'B' no deriva de' A' en tu código. –

8

Una opción sería la creación de una clase de código auxiliar que se puede utilizar para la fundición a la clase base derecha subobjeto:

struct A { 
    void fa() { } 
}; 

struct B : A { 
    void fb() { } 
}; 

// Use a stub class that we can cast through: 
struct A_ : A { }; 

struct C : A_, B { 
    void fc() { 
     implicit_cast<A_&>(*this).fa(); 
    } 
}; 

donde se define implicit_cast como:

template <typename T> struct identity { typedef T type; } 

template <typename T> 
T implicit_cast(typename identity<T>::type& x) { return x; } 
+0

Lo admito, yo Estoy desconcertado por la pregunta, y estoy muy interesado en si hay una manera de hacerlo sin inyectar una clase de código auxiliar en el enrejado. –

+0

Usar un stub es una buena solución, no creo que haya ninguna manera de lograr este comportamiento sin ese truco. ¡Esa es una limitación del lenguaje que nunca he considerado! –

+0

¿Por qué está utilizando un 'implicit_cast' en lugar de' static_cast'? Encuentro una publicación SO que responde mi pregunta, pero quizás podría agregar una pequeña explicación o un enlace a alguna información sobre eso. –

0

No creo que puedas hacer lo que quieras. Aquí hay una ambigüedad: cuando dices A::fa(), todavía no le dice al compilador qué objeto A usar. No hay forma de acceder a la clase A. Eso es lo que la advertencia te está diciendo.

Esto parece una construcción terriblemente extraña, sin embargo. La herencia pública se debe usar para las relaciones is-a. Usted dice que C es-a A dos veces? No tiene sentido. Y eso sugiere que este es un ejemplo artificial que nunca surgiría en la práctica, o debería reconsiderar este diseño.

5

Acabo de encontrar la siguiente información del estándar ISO C++ 2003 (10.1.3)

A class shall not be specified as a direct base class of a derived class more than once. [Note: a class can be 
an indirect base class more than once and can be a direct and an indirect base class. There are limited 
things that can be done with such a class. The non-static data members and member functions of the direct 
base class cannot be referred to in the scope of the derived class. However, the static members, enumerations 
and types can be unambiguously referred to. 

Significa que no hay manera directa :(

Cuestiones relacionadas