Reputation: 724
I am just working on my school homework, and I am interested if C++ could create specialized destructor for pointers. I know that this is not good practice, but because of performance, I want to do it this way. Also because I am curious about it. So lets say, that we have this 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();
}
Now I want destructor, that delete just node, if is T only type and delete also inner instance, if is T pointer..
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;
}
But this give me "invalid use of incomplete type". I also want to use pure C++11, because I want to be independent to another libraries (also standards libraries), moreover that libraries are not permitted in out system. Is something like this possible in pure C++?
Upvotes: 0
Views: 1317
Reputation: 2222
You can not partially specialize a member function. But you can partially specialize a class template:
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);
}
Or overload a function :
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);
}
Upvotes: 1
Reputation: 93274
You're giving your BinomialHeapLite
class a responsibility that it shouldn't have: cleaning up instance
if it's a heap-allocated pointer.
That burden should be on the user of your class: what if he is already calling delete
in its own code? What if the object is supposed to be reused after your BinomialHeapLite
is destroyed?
All your class should do is provide a generic container that manages its own memory. For that task, your should also use smart pointers (std::unique_ptr
in this case):
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;
}
You won't need an hand-written destructor then. Refer to the "rule of three/five/zero" for more information.
If you really want to implement your flawed/unconventional design, you could use a partially specialized helper struct that calls delete
if its type is a pointer:
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;
}
Upvotes: 1