Pregunta

Me gustaría para comprobar el tipo de un A superclase contra el tipo de un B subclase (con un método dentro de la A superclase, de modo que B la heredará).

Esto es lo que pensé resolvieron el problema (es decir, el uso de la declaración adelantada):

#include <iostream>
#include <typeinfo>

using namespace std;

class B;

class A {
  public:
    int i_;
    void Check () {
      if (typeid (*this) == typeid (B))
        cout << "True: Same type as B." << endl;
      else
        cout << "False: Not the same type as B." << endl;
    }
};

class B : public A {
  public:
    double d_;
};


int main () {

  A a;
  B b;

  a.Check (); // should be false
  b.Check (); // should be true

  return 0;
}

Sin embargo, este código no compila. El error que consigo es:

main.cc: In member function ‘void A::Check()’:
main.cc:12: error: invalid use of incomplete type ‘struct B’
main.cc:6: error: forward declaration of ‘struct B’

¿Cómo podría solucionar este problema?

¿Fue útil?

Solución

Creo que el problema que está tratando de resolver es mucho mejor manejado por un método virtual:

class A
{
    public:
        virtual bool Check() { return false; };
}


class B : public A
{
    public:
        // override A::Check()
        virtual bool Check() { return true; };
}

Los métodos de la clase base A no deben necesitar saber si el objeto es "realmente" una A o una B. Eso es una violación de los principios básicos de diseño orientado a objetos. Si el comportamiento tiene que cambiar cuando el objeto es un B, entonces ese comportamiento debe ser definido en B y manejado por las llamadas a métodos virtuales.

Otros consejos

Basta con mover la definición de verificación () fuera del cuerpo de A:

#include <iostream>
#include <typeinfo>

using namespace std;

class B;

class A {
  public:
    int i_;
    void Check ();
};

class B : public A {
  public:
    double d_;
};

void A::Check () {
  if (typeid (*this) == typeid (B))
    cout << "True: Same type as B." << endl;
  else
    cout << "False: Not the same type as B." << endl;
}

int main () {

  A a;
  B b;

  a.Check (); // should be false
  b.Check (); // should be true

  return 0;
}

Una forma sería la de tirar de la definición de Check fuera de la definición de clase, por lo que se define B cuando el compilador llega a la definición de la función.

class A {
    //...
    void Check();
    //...
};
class B { /* ... */ };

void A::Check() {
    //...
}

Mueva su definición de la comprobación por debajo de su declaración de la clase B.

Basta con mover el cuerpo de la función después de la declaración de B.

#include <iostream>
#include <typeinfo>

struct A
{
    int i_;
    void Check();
};

struct B :  A
{
    double d_;
};

void A::Check()
{
    using namespace std;
    if (typeid (*this) == typeid (B))
    {
        cout << "True: Same type as B." << endl;
    }
    else
    {
        cout << "False: Not the same type as B." << endl;
    }
}

int main()
{
    A a;
    B b;

    a.Check(); // should be false
    b.Check(); // should be true

    return 0;
}

Hola, incluso si usted pone la definición de A :: Compruebe fuera de la clase, el resultado no será el esperado. Esto es porque el objeto B este convertir a un Un objeto en el método por lo que este puntos en una Un objeto así los typeids son siempre diferentes. Para resolver este declarar el método virtual.

Sin embargo, todavía no entiendo por qué quiere realizar una prueba de este tipo O_o ?? Y como dijo CAdaker esto no es una buena práctica

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top