析构函数的部分特化

时间:2016-11-20 20:56:30

标签: c++ c++11 templates template-specialization partial-specialization

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

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;
}

但是这给了我&#34;无效使用不完整类型&#34;。我也想使用纯C ++ 11,因为我想独立于另一个库(也是标准库),而且在系统中不允许使用库。 在纯C ++中是否可以这样?

2 个答案:

答案 0 :(得分:1)

您的BinomialHeapLite课程负责不应该:如果它是堆分配的指针,则清理instance

这个负担应该对你班级的用户:如果他已经在自己的代码中调用了delete该怎么办?如果在BinomialHeapLite被销毁之后该对象应该被重用,该怎么办?

您的所有课程应该提供一个管理自己的内存的通用容器。对于该任务,您还应该使用智能指针 (在这种情况下为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"

如果你真的想要实现你的有缺陷/非常规设计,你可以使用一个部分专用的辅助结构,如果它的类型是指针,则调用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

答案 1 :(得分:1)

您不能部分专门化成员函数。但是你可以部分地专门化一个类模板:

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);
}