Domanda

Vorrei verificare il tipo di un A superclasse contro il tipo di un B sottoclasse (con un metodo all'interno del A superclasse, in modo che B erediterà esso).

Ecco quello che ho pensato che ha fatto il trucco (vale a dire, l'uso di dichiarazione anticipata):

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

Tuttavia questo codice non viene compilato. L'errore che ottengo è:

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’

Come potrei risolvere questo problema?

È stato utile?

Soluzione

Credo che il problema che si sta tentando di risolvere è molto meglio gestita da un metodo virtuale:

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


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

I metodi della classe base A non dovrebbe essere necessario sapere se l'oggetto è "realmente" una A o una B. Questo è una violazione dei principi di base orientati agli oggetti di design. Se il comportamento deve cambiare quando l'oggetto è un B, allora quel comportamento dovrebbe essere definito in B e gestito da chiamate metodo virtuale.

Altri suggerimenti

Basta muovere la definizione di Check () fuori dal corpo di 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;
}

Un modo sarebbe quello di tirare la definizione di Check fuori della definizione della classe, in modo che B viene definita quando il compilatore arriva alla definizione di funzione.

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

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

Sposta il definizione del Controlla qui sotto la tua dichiarazione di classe B.

Basta muovere il corpo della funzione dopo la dichiarazione di 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;
}

Ciao, anche se si mette la definizione di A :: Controllare al di fuori della classe il risultato non sarà quello che vi aspettate. Questo perché l'oggetto B questo convertire in un oggetto nel metodo così questo indica una Un oggetto così i typeids sempre diverse. Per risolvere questo dichiarare il metodo virtuale.

Comunque, io continuo a non capire perché si vuole eseguire tale O_o di prova ?? E come ha detto CAdaker questo non è buona pratica

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top