You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用接收std::vector<Animal*>的函数清理派生类vector以避免代码重复

搞定通用动物列表清理:避免重复代码的两种方案

嘿,这个场景太常见了——不想写两遍几乎一样的清理逻辑?完全没问题,我们可以用C++的模板或者多态特性来搞定,下面给你两种靠谱的方案:

方案一:用模板函数实现通用清理

既然Cat和Dog都是Animal的派生类,我们可以写一个模板函数,让它能处理任意存储Animal子类指针的vector,一套逻辑走天下:

class House {
private:
    std::vector<Cat*> cats;
    std::vector<Dog*> dogs;

    // 私有模板辅助函数,负责清理任意Animal子类的vector
    template<typename AnimalSubclass>
    void clearAnimalList(std::vector<AnimalSubclass*>& animalList) {
        // 逐个释放对象内存
        for (auto* animal : animalList) {
            delete animal;
        }
        // 清空vector
        animalList.clear();
    }

public:
    // 一次性清理所有动物
    void clearAllAnimals() {
        clearAnimalList(cats);
        clearAnimalList(dogs);
    }

    // 也可以单独清理某一类
    void clearCats() { clearAnimalList(cats); }
    void clearDogs() { clearAnimalList(dogs); }
};

这个方案的优点很明显:

  • 彻底消除重复代码,新增任何Animal子类(比如Bird),直接调用clearAnimalList(birds)就行
  • 类型安全,模板会自动推导子类类型,不会有类型错误
  • 逻辑清晰,把通用的清理逻辑封装在模板里,对外只需要调用简单的接口

方案二:适配你想要的clearList(std::vector<Animal*>)签名

如果你坚持要用这个函数签名,这里要注意:vector<Cat*>不能直接转成vector<Animal*>(容器类型不匹配),但我们可以用模板重载来适配:

class House {
private:
    std::vector<Cat*> cats;
    std::vector<Dog*> dogs;

    // 基类指针版本的清理函数
    void clearList(std::vector<Animal*>& animalList) {
        for (auto* animal : animalList) {
            delete animal;
        }
        animalList.clear();
    }

    // 模板重载,处理子类指针的vector
    template<typename T>
    void clearList(std::vector<T*>& animalList) {
        // 子类指针可以安全转成基类指针,然后调用基类版本的逻辑
        for (auto* animal : animalList) {
            delete static_cast<Animal*>(animal);
        }
        animalList.clear();
    }

public:
    void clearAllAnimals() {
        clearList(cats);
        clearList(dogs);
    }
};

不过说实话,这个方案和模板方案本质差不多,只是更贴合你最初设想的函数名而已。

关键注意事项!

一定要给Animal类加虚析构函数!不然通过Animal*指针删除子类对象时,只会调用基类的析构函数,子类的资源没法正确释放,会导致内存泄漏:

class Animal {
public:
    virtual ~Animal() = default; // 必须是虚析构!
    // 其他成员...
};

另外,如果以后改用智能指针(比如std::unique_ptr<Cat>),就不用手动delete了,直接调用animalList.clear()就行,模板函数依然适用,只需要删掉delete那行代码~

内容的提问来源于stack exchange,提问作者Gabel Luc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:53:06