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

如何自动判断C++内存是通过scalar new还是array new分配的?

解决智能指针自动区分标量/数组类型的方案

你可以通过以下几种方式实现自动判断,无需手动传入布尔值:

1. 工厂函数区分场景

提供专门的工厂函数来分别创建标量和数组类型的智能指针,内部自动设置标记位,代码更直观且不易出错:

template<typename T>
class Pointer {
public:
    // 私有构造函数,仅让工厂函数调用
    Pointer(T* ptr, bool is_array) 
        : m_ptr(ptr), m_is_array(is_array), m_ref_count(new size_t(1)) {}

    ~Pointer() {
        if (--*m_ref_count == 0) {
            m_is_array ? delete[] m_ptr : delete m_ptr;
            delete m_ref_count;
        }
    }

    // 其他成员函数...

private:
    T* m_ptr;
    bool m_is_array;
    size_t* m_ref_count;
};

// 创建标量智能指针
template<typename T>
Pointer<T> make_pointer(T* ptr) {
    return Pointer<T>(ptr, false);
}

// 创建数组智能指针
template<typename T>
Pointer<T> make_pointer_array(T* ptr) {
    return Pointer<T>(ptr, true);
}

使用时直接调用对应函数:

auto scalar_ptr = make_pointer(new int(42));
auto array_ptr = make_pointer_array(new int[5]);

2. 封装内存分配逻辑(推荐)

模仿标准库std::make_unique,让工厂函数直接完成内存分配,彻底避免用户手动调用new/new[],从根源上保证分配与释放方式匹配:

// 标量版本:直接构造对象
template<typename T, typename... Args>
Pointer<T> make_pointer(Args&&... args) {
    return Pointer<T>(new T(std::forward<Args>(args)...), false);
}

// 数组版本:指定大小分配
template<typename T>
Pointer<T> make_pointer_array(std::size_t size) {
    return Pointer<T>(new T[size], true);
}

使用示例:

auto scalar_ptr = make_pointer<int>(42);
auto array_ptr = make_pointer_array<int>(5);

3. 标签分派提升可读性

用空标签结构体替代布尔值,让构造逻辑更清晰:

// 定义标签
struct scalar_tag {};
struct array_tag {};

template<typename T>
class Pointer {
public:
    Pointer(T* ptr, scalar_tag) 
        : m_ptr(ptr), m_is_array(false), m_ref_count(new size_t(1)) {}
    Pointer(T* ptr, array_tag) 
        : m_ptr(ptr), m_is_array(true), m_ref_count(new size_t(1)) {}

    // 析构函数及其他成员...
};

// 辅助函数
template<typename T>
Pointer<T> make_scalar(T* ptr) {
    return Pointer<T>(ptr, scalar_tag{});
}

template<typename T>
Pointer<T> make_array(T* ptr) {
    return Pointer<T>(ptr, array_tag{});
}

关键注意事项

  • 务必保证分配方式与释放方式严格匹配:new对应delete,new[]对应delete[],否则会触发未定义行为。上述方案的核心就是将分配和释放的逻辑绑定,避免用户手动出错。
  • 如果需要支持数组的operator[],可以在类中添加条件重载,或者参考标准库std::unique_ptr<T[]>的模板特化方案实现更彻底的区分。

内容的提问来源于stack exchange,提问作者user21907176

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 16:13:18