2 Stimmen

Weiterleitungserklärung und typeid

Ich würde gerne den Typ einer Superklasse überprüfen A gegen den Typ einer Unterklasse B (mit einer Methode innerhalb der Oberklasse A , so dass B erben wird).

Hier ist, was ich dachte, hat den Trick gemacht (d.h. die Verwendung der Vorwärtserklä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;
}

Dieser Code lässt sich jedoch nicht kompilieren. Der Fehler, den ich bekomme, 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 könnte ich dieses Problem lösen?

3voto

JSBձոգչ Punkte 39615

Ich denke, dass das Problem, das Sie zu lösen versuchen, viel besser mit einer virtuellen Methode gelöst werden kann:

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 sollten nicht wissen müssen, ob das Objekt "wirklich" ein A oder ein B ist. Das ist ein Verstoß gegen grundlegende objektorientierte Entwurfsprinzipien. Wenn sich das Verhalten ändern muss, wenn das Objekt ein B ist, dann sollte dieses Verhalten in B definiert und durch virtuelle Methodenaufrufe behandelt werden.

1voto

jon-hanson Punkte 7951

Verschieben Sie einfach die Definition von Check() aus dem Körper von A heraus:

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

0voto

CAdaker Punkte 13449

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

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

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

0voto

Jesse Vogt Punkte 15441

Verschieben Sie die Definition der Prüfung unter die Erklärung der Klasse B.

0voto

DrPizza Punkte 17330

Verschieben Sie einfach den Funktionskörper nach der Deklaration 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;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X