假设我有一个抽象类Cat,它有几个具体的子类,例如野猫、家猫等。
我希望我的数组能够存储指向某种类型的猫的指针,而不知道它到底是哪种类型。
当我尝试动态分配一个Cat数组时,似乎并没有起作用。
Cat* catArray = new Cat[200];
假设我有一个抽象类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) 在完成任务后别忘了删除catArray中分配的实例,如delete catArray[0]等。
b) 别忘了使用delete删除catArray本身。
delete [] catArray;
你还应考虑使用向量来自动化b)
您需要创建一个指向 Cat
的指针数组:
Cat** catArray = new Cat*[200];
Cat
是具体类,如果你创建了一个 Cat
数组,仍然会遇到对象切片问题。std::vector
替代数组,并且应该使用智能指针来确保你的代码是异常安全的。你不能在固定大小的笼子里圈养猫,因为编译器无法知道猫的大小,也不知道如何初始化它们(隐喻失败)。你需要将数组初始化为空猫指针或其他方式,并稍后再进行操作。
你不能直接实例化一个抽象类的实例,而必须实例化一个完全实现了的子类的实例。
所以这是合法的:
Housecat* theCats = new Housecat[200];
然后你可以通过Cat接口访问每只猫
bool catsMeow = ((Cat*)(&theCats[0]))->CanMeow();
但编译器无法知道如何实例化抽象类;事实上,它是抽象的意味着它不能直接被实例化。
为什么要这样做?因为Cat将有一个抽象方法。
bool CanMeow() = 0;
所有继承自猫的类都必须实现。然后你可以询问它是否能喵喵叫,有可能狮子的实例会返回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;
}
}