c++ - 模板类问题

标签 c++ templates

我遇到了以下问题。考虑这个(非常简化的)例子。我正在使用我们现有的模板类之一,我可以添加(在一定程度上)一些通用功能:

template<typename T> class myClass
{
public:
    typedef T element_type;
    explicit myClass(T* p = 0) : ptr(p) {}           
    ~myClass() { delete ptr; };    

    ......

private:
    T* ptr;    
};

我还使用了一个外部库(我显然无法调整),其中定义(比方说)struct notMine。由于这是一个 C 风格的库,一个人做了某种 notMine* nmPtr = createNotMine(); 调用,我需要记住 freeNotMine(nmPtr); 当我完成。

现在我想将 myClass 与指向 notMine 结构的指针一起使用,但问题是当 myClass 超出范围时,我“忘记”释放此 notMine 结构,它改为调用“delete”。

解决这个问题的好方法是什么?

  • 我是否创建派生自 myClass 的类,我可以在其中编写我自己的特定于此问题的析构函数?
  • 我是否调整 myClass 以便传递某种可选的通用 Destructor 对象?
  • 我是否调整 myClass 以便我可以(可选地)传递要在析构函数中调用的静态函数?

编辑:我可能没有正确解释自己,但是 myClass 已经在其他地方使用了,所以我不能简单地更改现有的析构函数来适应这个特定问题

最佳答案

为您立即实现

鉴于该类可以修改(保持向后兼容性),您可以扩展该类以包含自定义删除器来管理资源(具有合适的默认值)。然后可以为类需要维护的每种类型实现自定义删除器。

template <typename T>
struct DefaultDeleter {
    void operator()(T* ptr) const {
        delete ptr;
    }
}

struct NotMineDeleter { // or a specialisation of DefaultDeleter
    void operator()(notMine* nmPtr) const {
        if (nmPtr)
           freeNotMine(nmPtr);
    }
}

template<typename T, typename Deleter = DefaultDeleter<T> >
class myClass
{
public:
    typedef T element_type;
    explicit myClass(T* p = 0) : ptr(p) {}           
    ~myClass() { deleter_(ptr); };    

    ......

private:
    Deleter deleter_;
    T* ptr;    
};

myClass 现在可以按如下方式用于外部库;

myClass<notMine, NotMineDeleter> obj(createNotMine());

您还需要通过将它们设为 private: (C++03) 或将它们删除 来处理类 myClass 的拷贝和分配=delete; (C++11) 或适本地实现,即实现完整的复制和赋值语义。

您评论说复制和赋值实现得当(notMine* 指针也需要如此)。如果不是这种情况,那么您可能会遇到更多问题。

C++11 还带来了移动语义,可以实现将所有权从 myClass 的一个实例转移到另一个实例。

更好

std::unique_ptrstd::share_ptr 与调用 freeNotMine(nmPtr) 的自定义删除器一起使用。

RAII - 看起来你正在做的是实现一个经典的 RAII 类。这是一件非常好的事情,也是 C++ 中资源类的核心惯用用法之一。

上述双重删除器的替代方法

使用模板特化,可以简化实现(但本质上仍然为要维护的每种类型维护删除器)如下;

template <typename T>
struct Deleter {
    void operator()(T* ptr) const {
        delete ptr;
    }
}

template <>
struct Deleter<notMine> {
    void operator()(notMine* nmPtr) const {
        if (nmPtr)
           freeNotMine(nmPtr);
    }
}

template<typename T>
class myClass
{
public:
    typedef T element_type;
    explicit myClass(T* p = 0) : ptr(p) {}           
    ~myClass() { deleter_(ptr); };    

    ......

private:
    Deleter<T> deleter_;
    T* ptr;    
};

myClass 现在可以按如下方式用于外部库;

myClass<notMine> obj(createNotMine());

关于c++ - 模板类问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25324907/

相关文章:

c++ - 专门化模板类构造函数

javascript - 带有外部 html 模板的 jsBlocks

c++ - 我如何在不知道 float 长度的情况下进行 fscanf?

c++ - 编写一个函数来执行与 set_symmetric_difference 相同的工作

c++ - 隐式模板构造函数被忽略

c++ - 依赖于默认模板类型参数的非类型模板参数

c++ - 将子节点添加到 XML 结构的顶部。 boost 属性树

c++ - 如何将两个字节 * (secblock) 与运算符 'secblock<T, A>::operator+=' 连接起来

c++ - 以字符数组为参数的模板元编程

C++ 对可调用类型作为模板参数的约束