You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

模板类的shared_ptr通用类型声明及对象实例化问题

当然可以!用std::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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:03:38