1

C++ キャスト演算子について質問があります。

クラスMessageといくつかのサブクラスがあるとしますMessage1 Message 2

EventEventのクラスとさまざまなサブクラスがあるとします。Event 1 Event 2

IDどちらの場合も、サブクラスの型と(フィールドなど)を区別できます。

class Message {
....
int MessageID;
}

class Message1 : public Message {
//other fields;
}

class Message2 : public Message {
//other fields;
}

class Event {
int eventID;
}

class Event1 {
Message theMessage;

Message getMessage();
}

class Event2 {
Message theMessage;
}

この場合、インスタンス Event1 または Event2 を に挿入します。vector<Event> キャリアによってイベントを抽出するときに、Event1 のインスタンスがあることは確かですが、static_cast?を使用するのは正しいことです。例えば:

    Event theEvent = myVector.at(i);
    Event1 *e1 = static_cast<Event1*>(&theEvent);
    if(e1->getID() == xxx) {
    Message2 *m2 = static_cast<Message2*>(&e1->getMessage());
    }

問題があります: 最後のキャストの後、インスタンス情報が Message2 として表示されません (常にその親クラス Message の情報のみ)。この場合、dynamic_cast を使用する必要がありますか?

4

3 に答える 3

3

通常、派生クラスがある場合は、仮想関数を使用する必要があります。

あなたの例では、おそらくメッセージの「コンテンツ」は仮想関数を介して取得できます。

このキャスト:

    Event1 *e1 = static_cast<Event1*>(&theEvent);

動作しないでしょう。はatheEventよりも小さい- つまり、最初に しかなかったので、そこから得られるメッセージは「ランダムなガベージ」になることを意味します。Event1MessageEvent

イベント配列に「任意のタイプのイベント」を保存する場合は、そのタイプへのポインターを保存する必要がありますEvent。そうしないと、上記のスライスの問題に悩まされることになります。

于 2013-06-23T23:13:09.053 に答える
3

e1->getMessage()ポインターではなく、Message 型のオブジェクトを返します。したがって、データはスライスされます。さらに、ここで一時的にポインターをキャストします。

Message2 *m2 = static_cast<Message2*>(&e1->getMessage());

ポインターを返す場合は、これを行うことができます。

Message * getMessage() { return &theMessage; }

static_cast実行時チェックなしでベース ポインターを派生ポインターにキャストする正しい方法です。これを行う「より安全な」方法は、もちろん dynamic_cast 演算子を使用することです。これは、派生物をベースポインターまたは参照にキャストするときにランタイムチェックを実行するためです。static_cast(失敗しない独自のチェックを取得した場合、これらのチェックを回避するために固執するように言うと、ここで石打ちで死ぬと思います。;))

(私の意見では) 最善の方法は、基本クラスで適切な仮想インターフェイスを設計することです。この方法で、ベースから派生へのキャストを回避できます。

Eventさらに、 を使用する場合は、すべての をスライスしますvector<Event>vector<Event*>Base ポインターは派生オブジェクトを指している可能性がありますが、Base オブジェクトは派生データを保持できないため、派生オブジェクトのコレクションを持つためにのみ使用できます。Event(ベクトル内のすべての派生s が欠落theMessageし、 に含まれるデータのみが含まれEventます。)

于 2013-06-23T23:06:56.763 に答える
1

提示されたあなたのアイデアは完全に絶望的です。すべての基底クラスを構造体とベクトルに値で格納します。つまり、派生したものではなく、まさにその基本クラスの型になります。したがって、キャストは少し役に立ちません。

ポリモーフィックオブジェクトをコレクションまたは構造体に格納する方法をよく読む必要があります。(基本的には、所有権の問題を正しく整理する、ある種のポインターを介して)。

ストレージの問題を解決したら、キャスティングの問題に戻ることができます。これは比較的簡単です。

于 2013-06-23T23:14:40.800 に答える