7

supongamos un cierto código (legacy), que no puede ser tocado, declararusando hermana herencia

struct B{ 
public: 
    void f(){} 
}; 

y supongamos tener

struct A{ 
public: 
    virtual void f()=0; 
}; 

es posible hacer una Una llamada subclase B :: f sin llamar explícitamente f(), es decir, en lugar de

struct C: public A, public B{ 
    void f(){ 
    B::f(); 
    } 
}; 

tener algo como

struct C:virtual public A,virtual public B{ 

}; 

(tenga en cuenta que esta última clase es abstracta, por el compilador A :: f no está definida)

+2

¿Qué pasa con 'B :: f()'? Esa es la forma correcta de llamar a 'B :: f()'. –

+0

imagine que tiene 100 funciones;) –

+2

No, no hay forma de que las funciones de los miembros base puedan * implementar * funciones virtuales puras para otra clase base. Eso simplemente no funciona. Lo que tienes está bien. –

Respuesta

1

Directamente en C++, es imposible despachar polimórficamente en función de una coincidencia implícita de las funciones de B con las A's. Podría recurrir a algún tipo de generación de código usando gccxml u otros productos similares, pero si solo hay un centenar de funciones, una macro puede reducir el reenvío a una sola línea de todos modos, no vale la pena introducir herramientas adicionales a menos que tenga miles y miles de estos para hacer.

+0

"_dispatch polimórficamente basado en una coincidencia implícita de las funciones de B con A's_" G ++ _used_ para admitir las denominadas "firmas": [Tipo abstracción usando firmas] (http://gcc.gnu.org/onlinedocs/gcc-2.95 .3/gcc_5.html # SEC112) "En GNU C++, puede usar la firma de la palabra clave para definir una interfaz de clase completamente abstracta como un tipo de datos. Puede conectar esta abstracción con clases reales utilizando punteros de firma. (...) Subtipo se convierte independiente de la herencia. (...) Las firmas le permiten trabajar con las jerarquías de clases existentes como implementaciones de un tipo de firma ". – curiousguy

+0

@curiousguy: eso es de interés general (retiro dado histórico en gcc 3), pero no veo cómo fue útil para hacer lo que busca la pregunta o más generalmente el "envío polimórficamente basado en alguna coincidencia implícita de las funciones de B a A "cito. Dada la firma 'S {void f(); }; ... S * p = static_cast (esto); p-> f(); 'parece funcionalmente equivalente a decir' std :: function x = std :: bind (& B :: f, this); x(); '- ambos parecen más torpes que llamar' B :: f(); 'como en la pregunta. ¿No estoy seguro si me estoy perdiendo algo ...? –

0

Se podría hacer algo como:

void C::f() { 
    B* b = this; 
    b->f(); 
} 
+0

gracias, pero no quiero escribir la implementación de cada función (además, ¿cuál es el beneficio de esta versión sobre la que escribí?) –

+0

@FabioDallaLibera: No entiendo. Si no quiere escribir una función llamada 'f' en' C', ¿por qué declara esa función? No hay diferencia entre esta implementación de 'C :: f' y la tuya en este caso que no sea ésta no usa' B :: f' que quisieras evitar. –

0

No, no se puede hacer ese. Y a partir del fragmento que nos ha mostrado, parece que B debe ser miembro de C por composición en lugar de herencia. Simplemente tendrá que escribir algunas funciones de reenvío (o una secuencia de comandos para generarlas automáticamente).

1

Hacer una implementación de A que delega en B:

class A_Impl : public A 
{ 
public: 
    virtual void f() 
    { 
     b.f(); 
    } 
private: 
    B b; 
} 

Implementar C derivando de A_Impl:

class C: public A_Impl 
{ 
}; 

O, si sólo desea mostrar A en la jerarquía de herencia, se derivan públicamente desde A y privadamente desde A_Impl:

class C: public A, private virtual A_Impl 
{ 
}; 
-1

Entonces, tiene 100 funciones virtuales puras en A, implementaciones de esas funciones en B, y desea evitar escribir reimplementando todas esas funciones en C para llamar a B. No hay forma de que el compilador use La implementación de B es automática. En lugar de luchar con el compilador (¡perderás todo el tiempo!), reconsidera el gráfico de herencia. Tal vez hacer B una subclase de A y luego derivar C de B. O factorizar los 100 métodos de B y en una subclase concreta de A.

La programación es el arte de resolver problemas dentro de las limitaciones provistas por sus herramientas. Cuando se encuentra en desacuerdo con sus herramientas, necesita reconsiderar su enfoque al problema o utilizar diferentes herramientas.

+0

La pregunta dice que B no se puede tocar, por lo que no se puede convertir en una subclase de A, y no se pueden mover métodos fuera de ella. – Karu