假设我有一个抽象类 Cat,它有一些具体的子类 Wildcat、Housecat 等。
我希望我的数组能够存储指向某种猫的指针,而无需知道它到底是哪种猫。
当我尝试动态分配一个 Cat 数组时,它似乎不起作用。
Cat* catArray = new Cat[200];
假设我有一个抽象类 Cat,它有一些具体的子类 Wildcat、Housecat 等。
我希望我的数组能够存储指向某种猫的指针,而无需知道它到底是哪种猫。
当我尝试动态分配一个 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) 不要忘记删除 catArray 中分配的实例,如 delete catArray[0] 等。
b) 不要忘记使用删除 catArray 本身
delete [] catArray;
您还应该考虑使用向量为您自动化 b)
您需要创建一个指针数组Cat
:
Cat** catArray = new Cat*[200];
即使基类是Cat
具体的,如果你创建了一个.Cat
请注意,您可能应该使用 astd::vector
而不是数组,并且可能应该使用智能指针来确保您的代码是异常安全的。
您不能将猫围在固定大小的笼子中,因为编译器无法知道猫有多大,也无法知道(隐喻失败)如何初始化它们。您将需要做一些事情,比如将数组初始化为空猫指针或其他东西,然后再将它们聚集起来。
您不能直接实例化抽象类的实例,而必须实例化完全实现的子类的实例。
所以这是合法的:
Housecat* theCats = new Housecat[200];
然后就可以通过Cat接口访问每只猫了
bool catsMeow = ((Cat*)(&theCats[0]))->CanMeow();
但是编译器无法知道如何实例化一个抽象类;事实上,它是抽象的这一事实意味着它不能被直接实例化。
为什么要这样做?因为 Cat 会有一个抽象方法
bool CanMeow() = 0;
所有继承的猫都必须执行。然后你可以问它是否可以喵喵叫,Lion 的实例可能会返回 false。
我在类似情况下所做的事情是循环遍历数组并将每个元素指向 nullptr。这样您就可以轻松地检查您是否已将派生类对象添加到插槽或它是否已打开。
Cat** catArray = new Cat*[200];
for(int i = 0; i < 200; i++){
catArray[i] = nullptr;
}
for(int i = 0; i < 200; i++){
if(catArray[i] != nullptr){
AddRealCat(...);
break;
}
}
I wonder if there's an easier way to do this, to check whether an element in an array of pointers to an abstract class points to an object of a derived class or is just an abstract pointer, without setting the element to nullptr. Like, is there a bool IsObject(ObjectType* ptr) or something in the standard library?
And, I wonder if setting each element to nullptr poses any potential problems, other than the computing cost of looping through the array and setting them to nullptr.
I posted this as an independent question (Array of Pointers to an Abstract Class: to nullptr or not to nullptr (C++)), but I thought it might be relevant here since this post is the closest to my question that I found when searching.