C++含模板抽象类的工厂模式设计问题求助
解决方案
核心问题是模板类的不同实例是完全独立的类型,Format<RGBData>和Format<PCMData>没有共同的非模板基类,因此无法用统一的指针类型返回。要实现工厂模式,需要先定义一个非模板的抽象基类作为所有格式类的统一接口。
步骤1:添加非模板抽象基类
在Formats内部定义不带模板的纯虚基类BaseFormat,保留所有格式类的公共接口:
class Formats { public: // 非模板抽象基类,作为统一接口 class BaseFormat { public: virtual bool writeFile() = 0; virtual ~BaseFormat() = default; // 必须定义虚析构,避免内存泄漏 }; // 模板类继承自BaseFormat,实现公共数据封装 template <typename T> class Format : public BaseFormat { protected: GlobalHandleLock<T> lock; public: Format(HGLOBAL mediaData) : lock(mediaData) {} // 直接初始化成员更高效 // 继承BaseFormat的纯虚函数,由派生类实现 virtual bool writeFile() = 0; }; // 改为public继承,否则工厂无法访问构造函数 class BMPFormat : public Format<RGBData> { public: BMPFormat(HGLOBAL mediaData) : Format(mediaData) {} bool writeFile() override; // 实现BMP写入逻辑 }; class WAVFormat : public Format<PCMData> { public: WAVFormat(HGLOBAL mediaData) : Format(mediaData) {} bool writeFile() override; // 实现WAV写入逻辑 }; };
步骤2:修改工厂类返回统一基类指针
工厂类现在可以返回Formats::BaseFormat*,所有具体格式类都兼容这个类型:
class FormatFactory { public: Formats::BaseFormat* getFormat(const std::string& formatName, HGLOBAL mediaData) { if (formatName == "BMP") { return new Formats::BMPFormat(mediaData); } else if (formatName == "WAV") { return new Formats::WAVFormat(mediaData); } // 处理未知格式,返回nullptr或抛出异常 return nullptr; } };
调用方式
调用方无需关心模板类型,直接通过工厂获取对象并调用接口:
FormatFactory formatFactory; HGLOBAL mediaData = ...; // 从剪贴板获取的数据 Formats::BaseFormat* format = formatFactory.getFormat("BMP", mediaData); if (format) { format->writeFile(); delete format; // 记得释放内存,或改用std::unique_ptr自动管理 }
关键说明
- 虚析构函数:
BaseFormat必须定义虚析构,否则通过基类指针删除派生类对象会触发未定义行为。推荐用std::unique_ptr替代裸指针,自动处理内存释放。 - 继承权限:具体格式类必须public继承
Format<T>,默认private继承会隐藏基类的public构造,导致工厂无法实例化对象。 - 扩展性:后续新增格式时,只需添加对应的派生类,并在工厂的
getFormat方法中新增分支即可,调用方代码无需修改。
内容的提问来源于stack exchange,提问作者tomysshadow
相关产品推荐
相关产品推荐

