我有一个班级Animal
,分别有两个派生类Cat
和Dog
。
我还有一个类House
,它包含两个列表作为属性:房子中每只猫的列表(std::vector<Cat*>
),以及每只狗的列表(vector<Dog*>
)。
我的目标是在House中编写一个功能,清除动物列表(void House::clearList( std::vector<Animal*> )
)。我希望尽可能避免重复代码。因此,为两个列表创建一个函数将是最佳的。
我想在House
的析构函数中调用此函数:
class Animal{};
class Dog : public Animal{};
class Cat : public Animal{};
class House{
private :
std::vector<Dog*> Dogs;
std::vector<Cat*> Cats;
public :
~House(){
clearList(dogs);
clearList(cats);
}
clearList(std::vector<Animal*> animals){
for (auto& animal : animals){
animal=nullptr;
delete animal;
}
}
};
编译器显示:
错误:没有匹配功能可以调用&#39;
House::clearList(std::vector<Cat*>&)
&#39; 注意:来自&#39;std::vector<Cat*>
&#39;的参数1没有已知的转化。到&#39;std::vector<Animal*>
&#39;
我无法在代码中使用shared_ptr
或unique_ptr
。
如何使用多态来解决这个问题?
答案 0 :(得分:2)
多态性不是你想要的。您可以使用模板,例如:
class Animal{
public:
virtual ~Animal(){}
};
class Dog : public Animal{};
class Cat : public Animal{};
class House{
private :
std::vector<Dog*> Dogs;
std::vector<Cat*> Cats;
template<typename T>
void clearList(std::vector<T*> &animals){
for (T *animal : animals){
delete animal;
}
animals.clear();
}
public :
~House(){
clearList(dogs);
clearList(cats);
}
};
如果你真的想为函数使用多态,那么你必须将vector
个对象更改为相同类型,然后你不需要模板,例如:
class Animal{
public:
virtual ~Animal(){}
};
class Dog : public Animal{};
class Cat : public Animal{};
class House{
private :
std::vector<Animal*> Dogs;
std::vector<Animal*> Cats;
void clearList(std::vector<Animal*> &animals){
for (Animal *animal : animals){
delete animal;
}
animals.clear();
}
public :
~House(){
clearList(dogs);
clearList(cats);
}
};
否则,只是不存储指针开头,让vector
自己的析构函数为你破坏对象:
class Animal{
public:
virtual ~Animal(){}
};
class Dog : public Animal{};
class Cat : public Animal{};
class House{
private :
std::vector<Dog> Dogs;
std::vector<Cat> Cats;
};
答案 1 :(得分:2)
要有效地使用多态,您需要两件事:虚函数,指针或对基类的引用。在你的情况下,因为你已经有了指针,只需要指向基类而不是派生类。而且由于你想要删除这些指针,所以将析构函数设为虚拟。