Frage

Ich möchte die Art eines Super A gegen den Typ einer Unterklasse B überprüfen (mit einer Methode innerhalb der übergeordneten Klasse A, so dass B sie erben werden).

Hier ist, was ich dachte, den Trick (das heißt, die Verwendung von Vorwärts-Erklärung):

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

Allerdings ist dieser Code nicht kompilieren. Der Fehler, den ich bekommen ist:

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’

Wie kann ich dieses Problem lösen?

War es hilfreich?

Lösung

Ich denke, dass das Problem, das Sie versuchen zu lösen ist viel besser gehandhabt durch eine virtuelle Methode:

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


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

Methoden in der Basisklasse A sollen nicht wissen müssen, ob das Objekt „wirklich“ ein A oder ein B Das ist eine Verletzung der grundlegenden objektorientierte Designprinzipien. Wenn das Verhalten Bedürfnisse zu ändern, wenn das Objekt ein B ist, dann ist das Verhalten sollte von virtuellen Methodenaufrufen in B und behandelt definiert werden.

Andere Tipps

Sie einfach die Definition von Check bewegen () aus dem Körper von 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;
}

Eine Möglichkeit wäre die Definition von Check aus der Klassendefinition zu ziehen, so dass B definiert ist, wenn der Compiler auf die Funktionsdefinition wird.

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

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

Bewegen Sie die Definition des Überprüfungs unten Ihre Erklärung der Klasse B.

Bewegen Sie einfach die Funktion Körper nach der Erklärung von 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;
}

Hallo, wenn Sie die Definition von A selbst setzen :: Prüfen außerhalb der Klasse nicht das Ergebnis, was Sie erwarten. Dies liegt daran, die B dieses convert zu einem A-Objekt in der Methode Objekt so deutet dies auf einem A-Objekt somit die typeids sind immer anders. Zur Lösung dieses declare der Methode virtuell.

Allerdings habe ich immer noch nicht verstehen, warum Sie einen solchen Test O_o ausführen wollen ?? Und wie CAdaker sagte, dies ist keine gute Praxis

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top