class B {
virtual int foo();
};
class D : public B {
virtual int foo() { cout<<"D\n"; }
};
int B::foo()
{
/* how do i tell if this->foo() is overridden by a subclass, or if it will */
/* simply recurse into B::foo()? */
this->foo();
}
main()
{
D d;
d.B::foo();
}
Respuesta
Respuesta: no se puede.
Expandiría si hubiera algo para expandir.
eso es lo que yo también pensé. – deltamind106
La forma más segura es no anular foo() en absoluto, pero permitir la anulación de una función OnFoo() que se llama desde la clase base si no puede confiar en sus programadores. MFC hace mucho de esto para garantizar un comportamiento predeterminado (en lugar de proteger contra la recurrencia).
Luego, también en un nivel estático, todo lo que implementa OnFoo() se detecta fácilmente con un 'Buscar en archivos'.
E.g. (No probado para la sintaxis/compilación y no-hilo)
class B
{
public:
B()
{
m_bInFoo=false;
}
int foo()
{
if(!m_bInFoo)
{
m_bInFoo=true;
int nRet = OnFoo();
m_bInFoo=false;
return nRet;
}
return 0;// probably throw exception
}
protected:
// inherited classes override OnFoo(), and never call OnFoo();
virtual int OnFoo(){ return 0 };
private:
bool m_bInFoo;
}
siquiera me gusta la prestación de este .. pero aquí es
int B::foo()
{
std::cout << "B" << std::endl;
if (typeid (*this) != typeid(B))
this->foo();
return 0;
}
Editar
Quiero demostrar que funciona en MSVC++ 2010.
#include "stdafx.h"
#include <iostream>
class B {
public:
virtual int foo();
};
class D : public B {
public:
virtual int foo() {
std::cout<<"D\n"; return 0;
}
};
int B::foo()
{
std::cout << "B" << std::endl;
/* how do i tell if this->foo() is overridden by a subclass, or if it will */
/* simply recurse into B::foo()? */
if (typeid (*this) != typeid(B))
this->foo();
return 0;
}
int main(int argc, _TCHAR* argv[])
{
D d;
d.B::foo();
B b;
b.foo();
return 0;
}
Ou tput
B
D
B
prueba no siempre funcionará
Cambio D para esto y no va a funcionar más
class D : public B { };
Eso no funciona. No está diciendo si foo() está anulado, y de hecho si no es su código recurrirá infinitamente en cualquier llamada a foo() en un objeto D; exactamente lo que el OP quiere evitar En realidad, no te ayuda a averiguar nada más allá de si el B en el que se invoca a foo() es en realidad una versión más específica o no ... eso es todo. Los puntos serían más significativos si la gente no se los entregara antes de verificar la validez de la respuesta. –
@ Noah Roberts Tiene razón, si D no anula B :: foo, recurrirá. Esto también se puede resolver usando el desenrollamiento de la pila. Cree una variable en la pila que establece una bandera en el almacenamiento local de subprocesos una vez que ingrese B :: foo(), si B: foo() se ingresa nuevamente a través de la misma pila e intenta crear otra variable, puede verificar si la bandera se ha configurado y luego sale. Una vez que la pila se desenrolla, la destrucción de la variable puede desarmar la bandera. Mi solución resuelve el problema exacto que él dio, que es mi culpa ya que no leí en otros escenarios que podrían haber ocurrido. –
Un enfoque es hacer foo()
función virtual pura en B
, y también lo definen. De esta manera, asegúrese de que las clases derivadas de B
deben definir foo()
. Aquí es B,
class B
{
public:
virtual int foo() = 0; //pure virtual function
};
//pure virtual function also has a default implementation!
int B::foo()
{
std::cout << "B" << std::endl;
this->foo(); //this will call the overridden foo() in the derived class!
return 0;
}
Si una clase derivada de B no implementa foo(), entonces ni siquiera se puede crear una instancia de esa clase derivada!
ver el código completo de trabajo en Ideone: http://www.ideone.com/m8O2s
Por cierto, mi opinión personal sería, como el diseño de las clases es malo para empezar. ¿Qué sucede si llama al B::foo()
desde la clase derivada foo()? Recursivo?
Esto lo hace para que no pueda instanciar una instancia de B. No sabemos si todavía quiere crear objetos de tipo B. –
sí, por supuesto, me doy cuenta de que hay muchas maneras de ingeniar a su alrededor, pero mi La pregunta es si hay una forma integrada en C++ rtti para hacer lo que quiero. – deltamind106
Como han señalado otros, no hay una manera confiable de hacerlo. Le insto a que reconsidere su diseño ...
bueno, sí, sería bueno si pudiera rediseñar el código incómodo del desarrollador anterior, pero lamentablemente eso no está en las tarjetas en este momento. – deltamind106
- 1. ¿Puede una clase base determinar si una clase derivada ha reemplazado a un miembro virtual?
- 2. ¿Por qué se llama al método de clase base si la clase derivada anula el método?
- 3. anula un método para una instancia de una clase?
- 4. C#: ¿Cómo puedo llamar a un método estático de una clase base desde un método estático de una clase derivada?
- 5. error constructor XmlSerializer con clase derivada de una clase base
- 6. C# - ¿Es posible reemplazar un método en una clase base dentro de la misma clase (NO una clase derivada)?
- 7. Pasando clase derivada a un método que necesita para anular esperando una clase base
- 8. Cómo serializar una clase derivada como su clase base
- 9. Accediendo a un miembro/método de una clase derivada virtual
- 10. Asignar clase derivada de la clase base
- 11. Convertir clase base a clase derivada
- 12. Cómo copiar/crear una instancia de clase derivada desde un puntero a una clase base polimórfica?
- 13. Método abstracto que devuelve una instancia de clase derivada
- 14. anula un método que usa una clase parcial
- 15. En Java, ¿cómo invoco el método de una clase base desde el método de anulación en una clase derivada?
- 16. ¿Cómo determinar si un objeto es una instancia de cierta clase derivada de C++ de un puntero a una clase base en GDB?
- 17. Compruebe si una clase tiene un método
- 18. ¿Cómo hacer una clase COM de ATL derivada de una clase base?
- 19. C# Reemplazando un método de clase base más de una cadena descendente de herencia de clase derivada
- 20. Pasando Clase derivada como parámetro de un método cuando el tipo de parámetro es clase base
- 21. C# inheritance. clase derivada de la clase Base
- 22. ¿Cómo se prueba una clase derivada de una clase base con muchas dependencias?
- 23. clase derivada Llamando al método estático de la clase base en su propio método estático
- 24. Ampliando un método de clase base
- 25. Java; clase base de conversión a la clase derivada
- 26. OOP Diferencia entre una clase derivada y una clase heredada?
- 27. C++ clase base de fundición a la clase derivada lío
- 28. Impresión del nombre de clase derivada en la clase base
- 29. ¿Cómo determinar programáticamente si la clase es una clase de caso o una clase simple?
- 30. Determinar si una clase implementa una interfaz muy específica
Probablemente no haya una manera confiable. ¿Por qué querrías? –
Estoy de acuerdo con Oli- simplemente llame a d.foo() como una persona normal. – Puppy
Quiero completar mi respuesta con algunos puntos de vista personales adicionales. Hago todo lo posible para nunca preguntarme por qué alguien quiere hacer algo. No puedo saber por qué quieren hacer algo, lo único que sé es que hicieron una pregunta.Creo que está bien tratar de resolver su problema Y proporcionar una alternativa que quizás no se les ocurra, pero las declaraciones como "hazlo como una persona normal" no son ni constructivas ni útiles. –