Wildcat、Housecat などの具体的なサブクラスがいくつかある抽象クラス Cat があるとします。
配列が実際の種類を知らなくても、猫の種類へのポインターを格納できるようにしたいと考えています。
Cat の配列を動的に割り当てようとすると、うまくいかないようです。
Cat* catArray = new Cat[200];
Wildcat、Housecat などの具体的なサブクラスがいくつかある抽象クラス Cat があるとします。
配列が実際の種類を知らなくても、猫の種類へのポインターを格納できるようにしたいと考えています。
Cat の配列を動的に割り当てようとすると、うまくいかないようです。
Cat* catArray = new Cat[200];
次のように、Cat へのポインターの配列を作成することにより、
Cat** catArray = new Cat*[200];
たとえば、WildCat、HouseCat などのインスタンスを配列内のさまざまな場所に配置できるようになりました。
catArray[0] = new WildCat();
catArray[1] = new HouseCat();
catArray[0]->catchMice();
catArray[1]->catchMice();
完了時のいくつかの注意事項a)
delete catArray[0] などのように、catArray に割り当てられたインスタンスを削除することを忘れないで
ください。b) を使用して catArray 自体を削除することを忘れないでください。
delete [] catArray;
vector を使用して b) を自動化することも検討する必要があります。
へのポインターの配列を作成する必要がありますCat
。
Cat** catArray = new Cat*[200];
基底クラスCat
が具体的であったとしても、Cat
.
std::vector
おそらく配列の代わりに a を使用する必要があり、コードが例外に対して安全であることを保証するためにスマート ポインターを使用する必要があることに注意してください。
コンパイラは猫がどれくらいの大きさになるか、また (メタファーの失敗) どのように初期化するかを知る方法がないため、固定サイズのケージに猫を切り詰めることはできません。配列をnull cat-pointersまたは何かに初期化し、後でそれらを群れにするようなことをする必要があります。
抽象クラスのインスタンスを直接インスタンス化することはできませんが、代わりに完全に実装されたサブクラスのインスタンスをインスタンス化する必要があります。
したがって、これは合法です:
Housecat* theCats = new Housecat[200];
その後、Catインターフェースを介して各猫にアクセスできます
bool catsMeow = ((Cat*)(&theCats[0]))->CanMeow();
しかし、コンパイラは抽象クラスをインスタンス化する方法を知る方法がありません。実際、それが抽象的であるということは、直接インスタンス化できないことを意味します。
なぜこれを行うのですか?Cat には抽象メソッドがあるため
bool CanMeow() = 0;
継承されたすべての猫が実装する必要があること。次に、Lion のインスタンスが false を返す可能性を考慮して、ニャーと鳴くことができるかどうかを尋ねることができます。