Question

Je voudrais vérifier le type d'un A superclasse contre le type d'une sous-classe de B (avec une méthode dans la superclasse A, de sorte que B héritera).

Voici ce que je pensais a fait l'affaire (c'est l'utilisation de la déclaration avant):

#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;
}

Toutefois, ce code ne compile pas. L'erreur que je reçois est:

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’

Comment pourrais-je résoudre ce problème?

Était-ce utile?

La solution

Je pense que le problème que vous essayez de résoudre est beaucoup mieux géré par une méthode virtuelle:

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


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

Méthodes dans la classe de base A ne devrait pas besoin de savoir si l'objet est « vraiment » un A ou un B. C'est une violation des principes de conception orientée objet de base. Si le comportement doit changer lorsque l'objet est un B, alors que le comportement doit être défini dans B et gérée par des appels de méthode virtuelle.

Autres conseils

Il suffit de déplacer la définition de Check () du corps 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;
}

Une façon serait de tirer la définition de Check de la définition de la classe, de sorte que B est définie lorsque le compilateur obtient à la définition de la fonction.

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

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

Passez votre définition de la vérification ci-dessous votre déclaration de classe B.

Il suffit de déplacer le corps de la fonction après la déclaration 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;
}

Salut, même si vous mettez la définition de A :: Vérifiez à l'extérieur de la classe le résultat ne sera pas ce que vous attendez. En effet, l'objet B cette conversion à un objet dans un la méthode donc ce fait sur un objet ainsi les A typeids sont toujours différents. Pour résoudre ce déclarer la méthode virtuelle.

Cependant, je ne comprends toujours pas pourquoi vous voulez effectuer un tel test O_o ?? Et comme CAdaker a dit que ce n'est pas une bonne pratique

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top