// 基类:定义虚方法
class Animal {
public:// 使用 virtual 声明可被重写的方法virtual void makeSound() {std::cout << "动物发出声音" << std::endl;}
};// 派生类1:重写基类方法
class Dog : public Animal {
public:// 使用 override 重写基类虚方法void makeSound() override {std::cout << "狗叫:汪汪" << std::endl;}
};
// 派生类2:重写基类方法
class Cat : public Animal {
public:void makeSound() override {std::cout << "猫叫:喵喵" << std::endl;}
};class Executor
{
public:template <typename Strategy, typename... Args>void SetGroupingStrategy(Args &&...args){m_strategy = std::make_unique<Strategy>(std::forward<Args>(args)...);}void makeSound();std::unique_ptr<Animal> m_strategy;
};void Executor::makeSound()
{m_strategy->makeSound();
}std::unique_ptr<Executor> g_animal;void learningFunc()
{cout << "函数派生demo测试" << endl;// 基类指针指向派生类对象(多态核心)Animal* animals[] = { new Animal(),new Dog(),new Cat() };// 动态绑定:根据实际对象类型调用对应方法for (Animal* animal:animals){animal->makeSound();// 输出结果取决于实际对象类型delete animal;}cout << endl << "Executor实例g_animal,并通过SetGroupingStrategy函数设置不同的策略类型!" << endl;g_animal = std::make_unique<Executor>();//动态绑定if (1){g_animal->SetGroupingStrategy<Animal>();g_animal->makeSound();g_animal->SetGroupingStrategy<Dog>();g_animal->makeSound();g_animal->SetGroupingStrategy<Cat>();g_animal->makeSound();}cout << "over!" << endl;
}
1. 基类与派生类定义
基类
Animal
:通过virtual
声明虚函数makeSound()
,允许派生类重写派生类
Dog
/Cat
:使用override
重写基类方法,编译器会检查函数签名一致性,避免错误多态性:通过基类指针调用
makeSound()
时,实际执行派生类的实现
2、策略执行器
Executor
模板方法
SetGroupingStrategy
:允许动态创建任意Animal
派生类对象,并通过std::forward
完美转发参数;智能指针管理:
std::unique_ptr<Animal>
确保资源自动释放,避免内存泄漏;多态调用:
m_strategy->makeSound()
根据实际对象类型执行对应方法;
3、全局对象与执行逻
全局执行器
g_animal
:通过std::make_unique
初始化,确保线程安全;策略切换:通过模板参数
<Animal>
、<Dog>
、<Cat>
动态更换策略,实现运行时多态;输出结果:依次调用不同策略的
makeSound()
,验证多态性;
二、关键机制与设计模式
1. 多态性实现
虚函数表(vtable):编译器为每个包含虚函数的类生成虚函数表,存储函数指针;
动态绑定:运行时根据对象实际类型调用对应方法,而非编译时静态绑定;
override 的作用:显式标记重写关系,防止因签名错误导致意外重载;
2. 模板策略模式
策略封装:将不同算法(
Animal
的叫声)封装为可互换的策略类;模板参数化:通过
SetGroupingStrategy<Strategy>
动态注入策略,提升扩展性;资源管理:使用
std::unique_ptr
自动释放策略对象,符合 RAII 原则;
总结:此代码通过虚函数与模板策略模式的结合,实现了灵活的多态行为扩展。核心优势在于运行时动态切换策略类型,同时保证了资源安全和代码可维护性