virtuales programas paso funciones ejemplos dev completo comandos basicos avanzados c++ virtual override diamond-problem

programas - manual completo de c++ pdf



Funciones de anulaciĆ³n virtual de C++ con el mismo nombre (4)

Como solución, intente

struct Impl_A : A { void Function () { cout << "A::Function" << endl; } }; struct Impl_B : B { void Function () { cout << "B::function" << endl; } }; struct Impl : Impl_A, Impl_B {};

Tengo algo así (simplificado)

class A { public: virtual void Function () = 0; }; class B { public: virtual void Function () = 0; }; class Impl : public A , public B { public: ???? };

¿Cómo puedo implementar la función () para A y la función () para B? Visual C ++ le permite solo definir la función específica en línea (es decir, no en el archivo cpp), pero supongo que es una extensión. GCC se queja de esto. ¿Existe una forma estándar de C ++ para decirle al compilador qué función deseo anular?

(visual c ++ 2008)

class Impl : public A , public B { public: void A::Function () { cout << "A::Function" << endl; } void B::Function () { cout << "B::Function" << endl; } };

¡Gracias!


No puedes usar nombres calificados allí. Si escribes void Function() { ... } , estás anulando ambas funciones. Herb Sutter muestra cómo se puede resolver .

Otra opción es cambiar el nombre de esas funciones, porque aparentemente hacen algo diferente (de lo contrario, no veo el problema de anular ambas con un comportamiento idéntico).


Puedo sugerir otra forma de resolver este problema. Puede agregar el tipo de contenedor que cambia la firma de la Function agregando un parámetro ficticio. De esta forma puedes distinguir los métodos en tu implementación.

class A { public: virtual void Function() = 0; virtual ~A() = default; }; class B { public: virtual void Function() = 0; virtual ~B() = default; }; template<typename T> class Typed : public T { public: virtual void Function(T* dummy) = 0; void Function() override { Function(nullptr); } }; class Impl : public Typed<A>, public Typed<B> { public: void Function(A* dummy) override { std::cerr << "implements A::Function()" << std::endl; } void Function(B* dummy) override { std::cerr << "implements B::Function()" << std::endl; } };

El beneficio de tal solución es que todas las implementaciones se colocan en una clase.


Si A y B son interfaces, entonces usaría derivación virtual para "unirlos" (hacer que se superpongan). Si necesita diferentes implementaciones para su Function si se llama a través de un puntero a A o a B , le recomiendo encarecidamente que elija otro diseño. Eso dolerá de lo contrario.

Impl "deriva de" A y B significa Impl "es un" A y B Supongo que no lo dices en serio.

Impl "implementa la interfaz" A y B significa que Impl "se comporta como" A y B entonces la misma interfaz debería significar el mismo comportamiento.

En ambos casos, tener un comportamiento diferente según el tipo de puntero utilizado sería "esquizofrénico" y es seguramente una situación que se debe evitar.