-
20-09-2019 - |
質問
私は(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’
私はこの問題を解決する可能性がどのように?
解決
私はあなたが解決しようとしている問題は、はるかに優れた仮想メソッドによって処理されていることを考えます
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で定義された仮想メソッド呼び出しによって処理されなければならない。
他のヒント
ただ、()の身体のチェックアウトの定義を移動
#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;
}
一つの方法は、コンパイラは、関数定義を取得するときCheck
が定義されているように、クラス定義の外にB
の定義を引っ張ることであろう。
class A {
//...
void Check();
//...
};
class B { /* ... */ };
void A::Check() {
//...
}
クラスBのあなたの宣言下のチェックのあなたの定義を移動します。
ちょうど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;
}
<時間>
こんにちは、 あなたはクラスの外::チェックの定義を入れても、結果はあなたが期待するものではありません。オブジェクト上のこの点は、このように型IDが常に異なるようにBオブジェクトがこの方法でオブジェクトに変換するためです。これを解決するには、仮想メソッドを宣言します。
あなたは、このようなテストO_Oを実行する理由しかし、私はまだ理解していません? CAdakerが言ったように、これは良い習慣ではありません。
所属していません StackOverflow