模板类的shared_ptr通用类型声明及对象实例化问题
先明确一点:类模板和std::shared_ptr完全兼容,不管是直接创建特定实例的智能指针,还是定义通用的智能指针模板类型,都能轻松实现。我结合你的场景一步步讲:
先假设你的Counter模板大概长这样(方便对照)
// Counter.hpp template <typename T> class Counter { private: T count; public: // 简单的构造函数,支持初始值 Counter(T initial = T{}) : count(initial) {} void increment() { ++count; } T get_count() const { return count; } };
方式1:直接创建特定类型的shared_ptr
这是最直接的用法,和普通类的shared_ptr用法几乎一样,只是要指定模板参数:
#include "Counter.hpp" #include <memory> // 必须包含这个头文件! #include <iostream> int main() { // 用make_shared创建int类型Counter的堆对象,初始值0 // auto可以自动推导类型,不用写长长的std::shared_ptr<Counter<int>> auto int_counter = std::make_shared<Counter<int>>(0); int_counter->increment(); std::cout << "Int counter value: " << int_counter->get_count() << std::endl; // 再创建一个double类型的 auto double_counter = std::make_shared<Counter<double>>(1.5); double_counter->increment(); std::cout << "Double counter value: " << double_counter->get_count() << std::endl; return 0; }
划重点:优先用
std::make_shared而不是new,它会一次性分配对象和智能指针的控制块内存,更高效,还能避免因异常导致的内存泄漏(比如new之后如果shared_ptr构造前抛出异常,内存就丢了)。
方式2:定义通用的shared_ptr模板类型(你想要的“通用类型”)
如果你希望有一个可以适配任意Counter<T>的通用智能指针类型,可以用模板别名来封装:
#include "Counter.hpp" #include <memory> // 定义一个模板别名,代表任意T类型的Counter的shared_ptr template <typename T> using CounterPtr = std::shared_ptr<Counter<T>>; int main() { // 现在可以用这个通用类型来声明变量 CounterPtr<int> int_ptr = std::make_shared<Counter<int>>(5); int_ptr->increment(); // 甚至可以配合make_shared简化创建,或者写个工厂函数更方便 CounterPtr<std::string> str_ptr = std::make_shared<Counter<std::string>>("start"); std::cout << "String counter value: " << str_ptr->get_count() << std::endl; return 0; }
进阶:写个工厂函数一键创建
如果要频繁创建不同类型的Counter智能指针,可以写个模板工厂函数,完美适配各种构造参数:
template <typename T, typename... Args> CounterPtr<T> make_counter_ptr(Args&&... args) { // 完美转发构造参数,适配Counter的任意构造函数 return std::make_shared<Counter<T>>(std::forward<Args>(args)...); } // 使用时超级简洁: auto my_counter = make_counter_ptr<int>(10); auto str_counter = make_counter_ptr<std::string>("hello");
几个注意事项
- 确保
Counter类模板的完整定义在头文件中(你已经做到了,因为Main.cpp能直接实例化,这点很重要,否则会出现链接错误); - 必须包含
<memory>头文件,std::shared_ptr和std::make_shared都在这里; - 智能指针的使用和普通指针类似,用
->访问成员函数/变量,不用手动delete,会自动管理内存。
内容的提问来源于stack exchange,提问作者ajax_velu
相关产品推荐
相关产品推荐

