C++ 使用带有类向量作为参数的函数清除派生类的向量
我有一个类C++ 使用带有类向量作为参数的函数清除派生类的向量,c++,c++11,C++,C++11,我有一个类Animal,分别有两个派生类Cat和Dog。 我还有一个类House,它包含两个属性列表:一个是房子里每只猫的列表(std::vector),一个是每只狗的列表(vector) 我的目标是在House中编写一个清除动物列表的函数(void House::clearList(std::vector))。我希望尽可能避免重复代码。因此,为两个列表创建一个函数是最佳的 我想在House的析构函数中调用此函数: class Animal{}; class Dog : public Anim
Animal
,分别有两个派生类Cat
和Dog
。
我还有一个类House
,它包含两个属性列表:一个是房子里每只猫的列表(std::vector
),一个是每只狗的列表(vector
)
我的目标是在House中编写一个清除动物列表的函数(void House::clearList(std::vector)
)。我希望尽可能避免重复代码。因此,为两个列表创建一个函数是最佳的
我想在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;
}
}
};
类动物{};
犬类:公共动物{};
猫类:公共动物{};
班房{
私人:
性病:病媒狗;
病媒猫;
公众:
~House(){
清除名单(狗);
清除名单(猫);
}
清晰列表(std::媒介动物){
用于(自动和动物:动物){
动物=无PTR;
删除动物;
}
}
};
编译器显示:
错误:调用“House::clearList(std::vector&”)
”时没有匹配的函数
注意:参数1没有从“std::vector
”到“std::vector
”的已知转换
我不能在我的代码中使用共享\u ptr
或唯一\u ptr
如何使用多态性来解决这个问题?多态性不是您想要的。您可以改用模板,例如:
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<Dog> Dogs;
std::vector<Cat> Cats;
};
类动物{
公众:
虚拟~Animal(){}
};
犬类:公共动物{};
猫类:公共动物{};
班房{
私人:
性病:病媒狗;
病媒猫;
};
多态性不是您想要的。您可以改用模板,例如:
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<Dog> Dogs;
std::vector<Cat> Cats;
};
类动物{
公众:
虚拟~Animal(){}
};
犬类:公共动物{};
猫类:公共动物{};
班房{
私人:
性病:病媒狗;
病媒猫;
};
要有效地使用多态性,您需要两样东西:虚拟函数和指向基类的指针或引用。在您的例子中,因为已经有了指针,所以只需将它们设为指向基类而不是派生类的指针即可。由于要删除这些指针,请将析构函数设置为虚拟的。要有效地使用多态性,需要两件事:虚拟函数和指向基类的指针或引用。在您的例子中,因为已经有了指针,所以只需将它们设为指向基类而不是派生类的指针即可。由于要删除这些指针,请将析构函数设置为虚拟。animal=nullptr;删除动物
可能不会像您认为的那样工作。“我不能在代码中使用shared_ptr或unique_ptr。”然后编写您自己的智能指针。通过值向函数传递向量可能会让调用方感到困惑,因为传递的实际向量不会更改,但它包含的指针将被删除。此外,既然从动物身上推导出了东西,为什么猫和狗有不同的载体呢?动物并没有一个虚拟的析构函数。事情不会有好的结局。animal=nullptr;删除动物
可能不会像您认为的那样工作。“我不能在代码中使用shared_ptr或unique_ptr。”然后编写您自己的智能指针。通过值向函数传递向量可能会让调用方感到困惑,因为传递的实际向量不会更改,但它包含的指针将被删除。此外,既然从动物身上推导出了东西,为什么猫和狗有不同的载体呢?动物并没有一个虚拟的析构函数。事情不会有好的结局。是的,你可以用多态性来完成,只需对程序做一些小的修改。模板有点高级。这比我想要给出的闻起来像是家庭作业问题的内容要详细一点。很高兴您指出了不使用指针的解决方案。非常感谢!它似乎像我想要的那样工作。我不确定我的编程老师会喜欢它,但我还是会试试;)是的,只需对程序进行一些小的更改,就可以使用多态性实现。模板有点高级。这比我想要给出的闻起来像是家庭作业问题的内容要详细一点。很高兴您指出了不使用指针的解决方案。非常感谢!它似乎像我想要的那样工作。我不确定我的编程老师会喜欢它,但我还是会试试;)“既然你已经有了指针,就让它们指向基类而不是派生类”-是的,但是每次你想访问它们时,你可能都必须键入cast。@GRC否,因为你的代码只需要必要的1/3左右。@RemyLebeau如果你想在这些对象上使用的所有方法都是虚拟的,你不需要任何演员。很难从这个玩具示例中知道这是否是一个问题。@RemyLebeau我非常感谢你的评论,但我想知道我遗漏了什么。:)@GRC:向量
、向量
和向量
是三种不同的类型,尽管它们基于相同的向量
实现。你不能像你所想的那样交换它们。“既然你已经有了指针,就让它们指向基类而不是派生类”-是的,但是每次你想访问它们时,你可能都必须键入cast。@GRC no,因为您的代码仅为所需代码的1/3左右。@RemyLebeau,如果您想在这些对象上使用的所有方法都是