析构函数的部分专业化

Partial specialization for destructor

我正在做我的学校作业,如果 C++ 可以为指针创建专门的析构函数,我很感兴趣。我知道这不是好的做法,但由于性能,我想这样做。也因为我对此很好奇。所以可以说,我们有这个 class:

template<typename T,int(*comp)(const T& first, const T& second)>
class BinomialHeapLite
{
private:
    class Node
    {
        Node* next;
        T instance;
    }
    Node* top;
public:
    ~BinomialHeapLite();
}

现在我想要析构函数,它只删除节点,如果是 T 仅类型并删除内部实例,如果是 T 指针..

template<typename T, int(*comp)(const T& first, const T& second)>
BinomialHeapLite<T,comp>::~BinomialHeapLite()
{
    //some code
    delete this->top;
}

template<typename T, int(*comp)(const T* &first, const T* &second)>
BinomialHeapLite<T*,comp>::~BinomialHeapLite()
{
    //some code
    delete this->top->instance;
    delete this->top;
}

但这给我"invalid use of incomplete type"。我还想使用纯 C++11,因为我想独立于另一个库(也是标准库),而且系统中不允许使用这些库。 在纯 C++ 中可以实现这样的功能吗?

你给你的 BinomialHeapLite class 一个 它不应该 的责任:清理 instance 如果它是一个堆-分配的指针。

这个负担应该 落在您 class 的用户身上:如果他已经在自己的代码中调用 delete 怎么办?如果对象应该在您的 BinomialHeapLite 被销毁后重新使用怎么办?

您 class 应该做的就是提供一个通用容器,该容器 管理自己的 内存。对于该任务,您还应该使用 智能指针 (在这种情况下为 std::unique_ptr):

template<typename T,int(*comp)(const T& first, const T& second)>
class BinomialHeapLite
{
private:
    class Node
    {
        std::unique_ptr<Node> next;
        T instance;
    }
    std::unique_ptr<Node> top;
}

到时候你就不需要手写的析构函数了。有关详细信息,请参阅 "rule of three/five/zero"


如果您真的想实现您的 flawed/unconventional 设计,您可以使用部分专用的辅助结构,如果它的类型是指针,则调用 delete

template <typename T>
struct dtor_helper
{
    static void do_it(T&&){}
};

template <typename T>
struct dtor_helper<T*>
{
    static void do_it(T* x){ delete x; }
};

template<typename T, int(*comp)(const T& first, const T& second)>
BinomialHeapLite<T,comp>::~BinomialHeapLite()
{
    //some code
    dtor_helper<T>::do_it(this->top->instance);
    delete this->top;
}

wandbox example

您不能部分特化成员函数。但是你可以部分特化一个 class 模板:

template <class T>
struct Deallocator{
  template <class Node>
  static void Deallocate(const Node &node){}
};

template <class T>
struct Deallocator<T *>{
  template <class Node>
  static void Deallocate(const Node &node){}
};

template<typename T, int(*comp)(const T& first, const T& second)>
BinomialHeapLite<T,comp>::~BinomialHeapLite()
{
    //some code
    Deallocator<T>::Deallocate(top);
}

或者重载一个函数:

template<typename T,int(*comp)(const T& first, const T& second)>
class BinomialHeapLite
{
private:
    struct Node // a little change here
    {
        Node* next;
        T instance;
    };
    Node* top;

    template <class Ty>
    void deallocate(Ty *) {}
    template <class Ty>
    void deallocate(Ty &) {}
public:
    ~BinomialHeapLite();
};

template<typename T, int(*comp)(const T& first, const T& second)>
BinomialHeapLite<T,comp>::~BinomialHeapLite()
{
    //some code
    deallocate(top->instance);
}