重複の可能性:
C++ で Static_cast を使用したダウンキャスト
基本オブジェクトへのポインターを派生クラスのポインターに変換する必要があるのはいつですか? 誰か私に例を挙げてくれませんか?
重複の可能性:
C++ で Static_cast を使用したダウンキャスト
基本オブジェクトへのポインターを派生クラスのポインターに変換する必要があるのはいつですか? 誰か私に例を挙げてくれませんか?
いつ
例を次に示します。
必要なオブジェクトの種類の文字列または列挙型を送信できるファクトリ (アニマル ファクトリ) があるとします...
「アニマルファクトリーさん、『犬』をください」
工場を書くには2つの方法があります...
次のように、すべての動物に対して関数を作成できます (優れたプログラマーはこれを行いません)。
または、次のように 1 つの関数でファクトリを作成することもできます (今のところ、ジェネリックについて考えないでください)。
Animal は実際には犬または猫であることを知っているので、Dog または Cat のメンバーにアクセスする必要があるときに、必要なものに型キャストできます...
C++ で行う私のお気に入りのことは、何かを取得するための一時的なキャストです (私の C++ は錆びているのを許してください)
Animal* myAnimal = Factory.GetAnimal("Dog");
int barkVolume = ((Dog*)myAnimal).BarkVolume;
基本クラスAnimal
と 2 つの派生クラスがあるCat
としDog
ます。
// Assume methods are public.
class Animal { virtual void Attack(); }
class Dog : public Animal { void Meow(); }
class Cat : public Animal { void Bark(); }
基本クラスポインターを使用して、派生オブジェクトを参照できます。これは、それらを同じタイプとして含めることができるようになったため役立ちます。
Animal* myCat = new Cat;
Animal* myDog = newDog;
std::vector<Animal*> myAnimals;
myAnimals.push_back(myCat);
myAnimals.push_back(myDog);
派生クラスの型に関係なく、すべての種類の動物の基本メンバー関数を呼び出すことができるため、これは便利です。
// Call Attack() on every cat and dog.
for_each(myAnimals.begin(), myAnimals.end(), [](auto& e) { e->Attack(); });
動的キャストを使用して、基本ポインターの 1 つを派生クラス ポインターに変換できるかどうかをテストできます。
Cat* realCat = dynamic_cast<Cat*> myAnimals[0]; // Success. Pointer is valid.
Cat* fakeCat = dynamic_cast<Cat*> myAnimals[1]; // Failure, it's not a cat. NULL.
Meow()
派生クラス ポインターなどから、メンバー メソッドを呼び出すことができるようになりました。Animal
にはこれらのメソッドがないため、これは以前は不可能でした。
realCat->Meow(); // Valid.
myCat->Meow(); // Animal*, there is not Meow() method.
どのような変換について話しているのですか?
ダウン キャスト(または同じ種類ですが、実行時に検証される動的キャスト)に関する場合は、指定した型を強制することで、型チェッカーがその特定の型を強制的にチェックしないようにすることができます。
これは、コード内での潜在的な中断であることを意味します。保証された型安全性がその特定の命令で欠落していますが、優れた設計ではアプリオリに必要とされない場合でも、必要になる場合があります。
必要なのは、キャストがないと、ベース クラスへのポインターに派生クラスが含まれていることが確実な場合でも、派生クラスのメソッドを呼び出すことが許可されないという事実によって与えられます (ただし、コンパイラーはそれを検証できません)。 )。
基本クラスに存在しない派生クラスのメンバーにアクセスするには、これを行う必要があります。ただし、優れたプログラミング手法とジェネリックを使用すると、基本クラスとして型指定されたポインターを持つべきではないでしょう。