2

Aスーパークラスのタイプをサブクラスのタイプと照合したいと思いますB(スーパークラス内のメソッドをA使用して、それBを継承します)。

これが私がトリックをしたと思ったことです(つまり、前方宣言の使用):

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

ただし、このコードはコンパイルされません。私が得るエラーは次のとおりです。

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’

どうすればこの問題を解決できますか?

4

6 に答える 6

3

あなたが解決しようとしている問題は、仮想メソッドによってはるかにうまく処理されると思います。

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


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

基本クラスAのメソッドは、オブジェクトが「本当に」AであるかBであるかを知る必要はありません。これは、基本的なオブジェクト指向の設計原則に違反しています。オブジェクトがBのときに動作を変更する必要がある場合、その動作はBで定義され、仮想メソッド呼び出しによって処理される必要があります。

于 2009-12-16T16:23:24.293 に答える
1

Check()の定義を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;
}
于 2009-12-16T16:20:50.487 に答える
0

Check1つの方法は、クラス定義からの定義をプルすることBです。これにより、コンパイラが関数定義に到達したときに定義されます。

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

void A::Check() {
    //...
}
于 2009-12-16T16:20:28.350 に答える
0

チェックの定義をクラスBの宣言の下に移動します。

于 2009-12-16T16:21:39.647 に答える
0

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;
}
于 2009-12-16T16:22:07.350 に答える
0

こんにちは、A :: Checkの定義をクラスの外に置いても、結果は期待したものにはなりません。これは、これがメソッド内でBオブジェクトをAオブジェクトに変換するため、これがAオブジェクトを指すため、タイプIDが常に異なるためです。これを解決するには、メソッドvirtualを宣言します。

しかし、なぜそんなテストをしたいのか、まだわかりませんO_o ?? そしてCAdakerが言ったように、これは良い習慣ではありません

于 2009-12-16T16:59:17.293 に答える