如何用C++模板在方法中切换自定义类类型?
解答
你的模板方案完全可行,这是C++中处理编译时多态的典型场景,能有效消除代码冗余。以下是几个优化方向,可提升代码的安全性、可读性和可维护性:
1. 替换裸指针为智能指针
当前代码使用new创建对象但未手动delete,存在内存泄漏风险。推荐使用std::unique_ptr管理对象生命周期,它会在作用域结束时自动释放内存:
#include <memory> template <typename T> int MasterMethod(double arg1, double arg2) { double classArg1 = some_weird_math_function((arg1-arg2), arg1); double classArg2 = some_weird_math_function((arg1-arg2), arg2); std::unique_ptr<T> obj = std::make_unique<T>(classArg1, classArg2); obj->another_weird_math_function(); return obj->GetAnswer(); }
2. 使用C++20概念约束模板参数
为确保模板参数T符合预期接口(指定构造函数和成员方法),可以用C++20的**概念(Concepts)**做编译时检查,提前发现类型不匹配的错误:
#include <concepts> #include <memory> template<typename T> concept CalculationClass = requires(T t, double d1, double d2) { // 要求T支持(double, double)构造 T(d1, d2); // 要求拥有无返回值的another_weird_math_function { t.another_weird_math_function() } -> std::same_as<void>; // 要求拥有返回int的GetAnswer { t.GetAnswer() } -> std::same_as<int>; }; template <CalculationClass T> int MasterMethod(double arg1, double arg2) { double classArg1 = some_weird_math_function((arg1-arg2), arg1); double classArg2 = some_weird_math_function((arg1-arg2), arg2); std::unique_ptr<T> obj = std::make_unique<T>(classArg1, classArg2); obj->another_weird_math_function(); return obj->GetAnswer(); }
如果传入的T不符合接口,编译器会给出清晰的错误提示,而非模糊的编译报错。
3. 模板 vs 多态方案的选择
如果后续需要运行时动态切换使用的类(比如根据配置参数选择),可以考虑基于基类的多态方案:
- 定义抽象基类:
class BaseCalculation { public: virtual void another_weird_math_function() = 0; virtual int GetAnswer() = 0; virtual ~BaseCalculation() = default; // 必须声明虚析构函数 };
- 让
Custom_Class和A_Different_Custom_Class继承并实现基类接口 - 编写接受基类指针/引用的通用函数,或配合工厂函数创建对象
不过这种方案会引入虚函数调用的性能开销,而你的模板方案是编译时多态,无运行时开销,更适合当前编译时确定类类型的场景。
4. 提取构造参数计算逻辑(可选)
如果构造参数的计算逻辑需要复用或后续可能修改,可将其提取为独立辅助函数,提升代码模块化程度:
#include <concepts> #include <memory> #include <utility> std::pair<double, double> calculateClassArgs(double arg1, double arg2) { double diff = arg1 - arg2; return { some_weird_math_function(diff, arg1), some_weird_math_function(diff, arg2) }; } template <CalculationClass T> int MasterMethod(double arg1, double arg2) { auto [classArg1, classArg2] = calculateClassArgs(arg1, arg2); std::unique_ptr<T> obj = std::make_unique<T>(classArg1, classArg2); obj->another_weird_math_function(); return obj->GetAnswer(); }
内容的提问来源于stack exchange,提问作者Samuel Brown
相关产品推荐
相关产品推荐

