使用带有类向量

时间:2018-04-18 23:47:30

标签: c++ c++11

我有一个班级Animal,分别有两个派生类CatDog。 我还有一个类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_ptrunique_ptr

如何使用多态来解决这个问题?

2 个答案:

答案 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)

要有效地使用多态,您需要两件事:虚函数,指针或对基类的引用。在你的情况下,因为你已经有了指针,只需要指向基类而不是派生类。而且由于你想要删除这些指针,所以将析构函数设为虚拟。