钩子函数是在基类中定义的带有默认实现的虚函数,子类可选择性地覆盖以扩展行为。它用于模板方法模式中的可选扩展点,如条件执行或前后置操作,无需强制子类实现,提供更高灵活性。示例中shouldValidate()为钩子函数,默认返回false控制是否验证数据,子类可根据需要重写。

模板方法模式在C++中通过基类定义算法骨架,子类实现具体步骤。钩子函数是该模式中的可选虚函数,允许子类选择性地扩展行为,而不需要强制重写。
什么是钩子函数
钩子函数(Hook Method)是在基类中定义的虚函数,提供默认实现,子类可以按需覆盖。它用于控制模板方法中的某些扩展点,比如条件执行、前置/后置操作等。
与抽象方法不同,钩子函数不是纯虚函数,子类无需必须实现,这使得其更具灵活性。
基本使用方式
定义一个基类,在其中声明模板方法,并加入一个或多个钩子函数作为扩展点。
立即学习“C++免费学习笔记(深入)”;
SmartB2B 是一款基于PHP、MySQL、Smarty的B2B行业电子商务网站管理系统,系统提供了供求模型、企业模型、产品模型、人才招聘模型、资讯模型等模块,适用于想在行业里取得领先地位的企业快速假设B2B网站,可以运行于Linux与Windows等多重服务器环境,安装方便,使用灵活。 系统使用当前流行的PHP语言开发,以MySQL为数据库,采用B/S架构,MVC模式开发。融入了模型化、模板
- 模板方法为非虚函数,封装算法流程
- 部分步骤由虚函数(包括钩子)实现,允许子类定制
- 钩子函数提供默认空实现或默认逻辑
示例代码:
class DataProcessor {
public:
// 模板方法:固定流程
void process() {
readData();
parseData();
if (shouldValidate()) { // 钩子函数调用
validateData();
}
saveData();
}
protected:
virtual void readData() = 0;
virtual void parseData() = 0;
virtual void saveData() = 0;
// 钩子函数:默认不验证
virtual bool shouldValidate() const {
return false;
}
virtual void validateData() {
std::cout << "Validating data...\n";
}
};
class FileProcessor : public DataProcessor {
protected:
void readData() override {
std::cout << "Reading from file...\n";
}
void parseData() override {
std::cout << "Parsing file content...\n";
}
void saveData() override {
std::cout << "Saving processed file...\n";
}
// 子类选择性覆盖钩子
bool shouldValidate() const override {
return true; // 启用验证步骤
}
};
实际应用场景
钩子函数适用于需要条件分支或可选行为的模板流程。
- 控制是否执行某一步骤(如上面的验证)
- 提供前置或后置处理(例如日志记录、资源清理)
- 支持调试模式开关
比如添加一个后置钩子:
virtual void postProcess() const {
// 默认为空,子类可扩展
}
void process() {
readData();
parseData();
if (shouldValidate()) {
validateData();
}
saveData();
postProcess(); // 扩展点
}
某个子类可用来打印统计信息:
void postProcess() const override {
std::cout << "Processing completed at: "
<< time(nullptr) << "\n";
}
基本上就这些。钩子函数让模板方法更灵活,子类能以最小代价参与流程控制,而不破坏整体结构。









