2011-09-16 4 views
1
私は、オブジェクトが dynamic_castを使用して 特定子クラス型である場合、親クラスのコンストラクタに渡されたポインタが唯一の NULLであることを主張しようとしている

C++では、オブジェクトがParentクラスのコンストラクタ内のChildクラスのインスタンスであるかどうかをどのようにテストできますか?

#include <iostream> 
class Parent { 
public: 
    Parent(void *ptr); 
    virtual ~Parent(); // to make Parent polymorphic 
}; 

class Child1 : public Parent { 
public: 
    Child1() : Parent(0) { std::cout << "Child1 ctor\n";}; 
}; 
class Child2 : public Parent { 
public: 
    Child2() : Parent(0) { std::cout << "Child2 ctor\n";}; 
}; 

Parent::Parent(void *ptr) { 
    if (0 == ptr && 0 == dynamic_cast<Child1*>(this)) { 
     std::cerr<<"ERROR\n"; 
    } 
} 
Parent::~Parent() {}; 

int main(void) { 
    Child1 *c1 = new Child1(); 
    Child2 *c2 = new Child2(); 
} 

この版画:

ERROR 
Child1 ctor 
ERROR 
Child2 ctor 

Child2の建設中にERRORが表示されると予想します。です。私はChild1のコンストラクタの初期化リストから呼び出さChild1ためParentコンストラクタにいるとき

はなぜdynamic_castは非NULLを返していますか?また、このテストを行うには別の方法がありますか?

+1

私は、このようなデザインが継承の "is-a"関係に違反すると感じています... –

+0

1)なぜあなたはこれをしたいですか? 2)あなたがこれを行うことができない理由は、子どもがまだ構築されていないからです。 –

+0

実際には、NULLポインタを持たない10個の異なる子クラスがありますが、NULLポインタを持つ1個の子クラスしかありません。私はこのチェックを10種類のクラスに入れないようにしています。 –

答えて

1

私は、dynamic_castがvtableを処理していることが問題だと思いますが、これはコンストラクタが終了するまで設定されていません。したがって、コンストラクタでdynamic_castを呼び出すことはできません。

私は、テンプレートを使用せずにすべてを静的にすることなく、コンストラクタでこれを検出する方法は考えられません。なぜあなたはこの行動を望んでいますか?それはかなり疑わしい - 親は本当に派生Child1とChild2の知識を持ってはいけません。

Child2が親コンストラクタを呼び出すときにnullポインタを保護したい場合、Child2のコンストラクタでChild2を保護し、nullの場合は例外をスローするのはなぜですか?

+0

多くのChild2があります。私はクラス全体の中に小切手を入れないようにしていました。 –

+2

CheckedParentクラスを作成し、それからChild2を派生させてみませんか? – Andrew

2

親コンストラクタ(基本クラス)にいるとき、子はまだ構築されていません。その結果、Parentのコンストラクタ内では、これの動的型は常にParentになります。

+0

RTTI情報はコンストラクタの各レベルによって繰り返し作成されますか? –

+0

いいえ、RTTI情報は静的であり、コンパイル時に構築されます。コンストラクタとデストラクタ内で、派生クラスはまだ構築されていないか、すでに破棄されています。しかし、オブジェクトの動的な型はコンストラクタの各レベルによって反復的に構築されると言うかもしれません。 –

0

基本的なクラスでプロジエクトされたコンストラクタを作成し、それを初期化する方法を示すパラメータを渡すことが1つの方法です。このように、子クラスは必要な方法を決定し、ベースクラスは要求どおりにアレンジします。

関連する問題