una resolucion programacion orientada operador objetos miembros metodos ejemplos codigo clases clase ambito c++ types

resolucion - Encontrar el tipo de un objeto en C++



operador de resolucion de ambito c++ (11)

¿Estás buscando dynamic_cast<B*>(pointer) ?

Tengo una clase A y otra clase que hereda de ella, B. Estoy anulando una función que acepta un objeto de tipo A como parámetro, así que tengo que aceptar una A. Sin embargo, luego llamo a funciones que solo B tiene, entonces quiero devolver falso y no proceder si el objeto pasado no es del tipo B.

¿Cuál es la mejor manera de descubrir qué tipo de objeto pasó a mi función?


Como otros indicaron, puedes usar dynamic_cast. Pero generalmente el uso de dynamic_cast para descubrir el tipo de clase derivada en la que está trabajando indica el diseño incorrecto. Si está sobrescribiendo una función que toma el puntero de A como parámetro, entonces debería poder trabajar con los métodos / datos de la clase A en sí misma y no debería depender de los datos de la clase B. En su caso, en lugar de anularlos, si está seguro de que el método que está escribiendo funcionará solo con la clase B, luego debe escribir un nuevo método en la clase B.


El reparto dinámico es lo mejor para su descripción del problema, pero solo quiero agregar que puede encontrar el tipo de clase con:

#include <typeinfo> ... string s = typeid(YourClass).name()


Esto se llama RTTI, pero seguramente querrá reconsiderar su diseño aquí, porque encontrar el tipo y hacer cosas especiales basadas en él hace que su código sea más frágil.


Porque tu clase no es polimórfica. Tratar:

struct BaseClas { int base; virtual ~BaseClas(){} }; class Derived1 : public BaseClas { int derived1; };

Ahora BaseClas es polimórfico. Cambié la clase a struct porque los miembros de una estructura son públicos por defecto.


Probablemente incruste en sus objetos una "etiqueta" de identificación y úselo para distinguir entre objetos de clase A y objetos de clase B.

Sin embargo, esto muestra un defecto en el diseño. Idealmente, los métodos en B que A no tiene, deben ser parte de A, pero deben dejarse vacíos, y B los sobrescribe. Esto elimina el código específico de clase y está más en el espíritu de OOP.


Si puede acceder a la biblioteca de impulso, tal vez la función type_id_with_cvr () es lo que necesita, que puede proporcionar el tipo de datos sin eliminar los modificadores const, volátil, & y && . Aquí hay un ejemplo simple en C ++ 11:

#include <iostream> #include <boost/type_index.hpp> int a; int& ff() { return a; } int main() { ff() = 10; using boost::typeindex::type_id_with_cvr; std::cout << type_id_with_cvr<int&>().pretty_name() << std::endl; std::cout << type_id_with_cvr<decltype(ff())>().pretty_name() << std::endl; std::cout << typeid(ff()).name() << std::endl; }

Espero que esto sea útil.


Solo para completar, construiré build de Robocide y typeid que typeid puede usarse solo sin usar name ():

#include <typeinfo> #include <iostream> using namespace std; class A { public: virtual ~A() = default; // We''re not polymorphic unless we // have a virtual function. }; class B : public A { } ; class C : public A { } ; int main(int argc, char* argv[]) { B b; A& a = b; cout << "a is B: " << boolalpha << (typeid(a) == typeid(B)) << endl; cout << "a is C: " << boolalpha << (typeid(a) == typeid(C)) << endl; cout << "b is B: " << boolalpha << (typeid(b) == typeid(B)) << endl; cout << "b is A: " << boolalpha << (typeid(b) == typeid(A)) << endl; cout << "b is C: " << boolalpha << (typeid(b) == typeid(C)) << endl; }

Salida:

a is B: true a is C: false b is B: true b is A: false b is C: false


Tu descripción es un poco confusa.

En términos generales, aunque algunas implementaciones de C ++ tienen mecanismos para ello, se supone que no debes preguntar sobre el tipo. En su lugar, se supone que debes hacer un dynamic_cast en el puntero a A. Lo que esto hará es que en el tiempo de ejecución, se verificará el contenido real del puntero a A. Si tiene una B, obtendrá su puntero a B. De lo contrario, obtendrá una excepción o nulo.


Use funciones sobrecargadas. No requiere soporte dynamic_cast o incluso RTTI:

class A {}; class B : public A {}; class Foo { public: void Bar(A& a) { // do something } void Bar(B& b) { Bar(static_cast<A&>(b)); // do B specific stuff } };


dynamic_cast debería hacer el truco

TYPE& dynamic_cast<TYPE&> (object); TYPE* dynamic_cast<TYPE*> (object);

La palabra clave dynamic_cast arroja un dato de un puntero o tipo de referencia a otro, realizando una verificación en tiempo de ejecución para garantizar la validez del elenco.

Si intenta convertir al puntero a un tipo que no es un tipo de objeto real, el resultado del molde será NULL. Si intentas convertir para hacer referencia a un tipo que no es un tipo de objeto real, el elenco lanzará una excepción bad_cast .

Asegúrese de que haya al menos una función virtual en la clase Base para que dynamic_cast funcione.