繁体   English   中英

使用以类的向量为参数的函数清除派生类的向量

[英]Clear a vector of derived classes using a function with a vector of class as argument

我有一个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;
            }
       }
};

编译器显示:

错误:没有匹配的函数可调用' House::clearList(std::vector<Cat*>&) '注:未知参数1从' std::vector<Cat*> '到' std::vector<Animal*> '

我不能在代码中使用shared_ptrunique_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<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;
};

为了有效地使用多态性,您需要做两件事:虚函数和基类的指针或引用。 在您的情况下,由于您已经有了指针,因此只需使它们指向基类而不是派生类的指针即可。 并且由于您要删除这些指针,因此将析构函数设为虚拟。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM