2017-02-25 59 views
0

我有一个模板类不工作检查和删除预期

template <class T> 
class Node 
{ 
    private: 
     T data; 

    public: 
     Node<T> *next; 
     Node(T initial); 
     ~Node(); 
};  

和析构函数如下:

template <class T> 
Node<T>::~Node() 
{ 
    if (std::is_pointer<T>::value) 
    { 
     delete this->data; 
    } 
} 

template <class T> 
LinkedList<T>::~LinkedList() { 
    Node<T> *this_nodes = this->head; 
    Node<T> *next = NULL; 

    while (this_nodes) 
    { 
     next = this_nodes->next; 
     delete this_nodes; 
     this_nodes = next; 
    } 
} 

然而,当我试图使用g ++与编译C++ 11 ,用下面的驱动程序代码

LinkedList<int> list; 
list.insert(5); 
assert(list.read() == 5); 

我得到以下错误:

error: type ‘int’ argument given to ‘delete’, expected pointer 

该节点是LinkedList的内部,我离开了,因为它不是完全有必要帮助回答这个问题。我不确定为什么会出现这个错误,因为我在尝试删除它之前已经确认数据是指针。

有人能让我进一步了解为什么这不起作用/替代方法? (注:不能使用智能指针这个任务)

+1

'删除这个 - >数据;' - '数据'是一个'int'。你为什么要“删除”它?包含的'Node '是应该删除的内容(事实上,正如此,否则你的析构函数将不会被触发)。如果你试图取消那些不是指针的东西的资格,那么代码本身应该被SFINAE或专业化的东西忽略掉;不在运行时的if块中。 – WhozCraig

+2

你为什么要删除'data'开头?不要管它。如果数据是动态分配的,你的班级不应该有任何想法。一个指针不需要用'new'分配,所以你的指针检查甚至不被保证。 – PaulMcKenzie

+0

驱动程序的其他部分使用其他元素,如int *,Card *(自定义类)和其他一些元素。这些数据不会被空的构造函数删除,我不知道如何适当释放内存。我知道数据是一个整数,因此if语句应该失败并且不做任何事情。它应该只反应,当我得到一个实际的指针作为类型(节点例如) – ZeldaZach

回答

1

if语句是在你的代码来创建运行分支机构的工具。没有条件编译。当扩大你的模板代码,它看起来与此类似:

Node<int>::~Node() 
{ 
    if (false) 
    { 
     delete this->data; 
    } 
} 

你还是删除INT,即使是枯枝,代码必须仍然有效。


解决方案应该确实不要触摸指针。你期望这个代码输出什么?

struct A { ~A() { std::cout << "~A()" << std::endl; } }; 

auto a = new A; 

std::vector<A*> vec; 

vec.emplace_back(a); 

vec.clear(); 

答案不算什么。该向量将删除他的缓冲区,但不会删除您的数据。如果您希望这种情况发生,使用std::unique_ptr

struct A { ~A() { std::cout << "~A()" << std::endl; } }; 

auto a = new A; 

std::vector<std::unique_ptr<A>> vec; 

vec.emplace_back(a); 

vec.clear(); 

现在有人会想到这个代码输出~A()。你的代码也是一样。通常情况下,您希望类型能够自行管理并释放任何获得的资源。因此,您的代码中的更改仅仅是删​​除删除并假定类型来管理自己。


如果你真的想反正这样做,我真的不建议,你可以这样做:

template<typename T> 
void deleteIfPtr(T* ptr) { delete ptr; } 

template<typename T> 
void deleteIfPtr(const T&) { /* else, do nothing */ } 

template <class T> 
Node<T>::~Node() 
{ 
    deleteIfPtr(this->data); 
} 
+0

我决定和unique_ptr一起去,谢谢你的协助! – ZeldaZach

0

不能使用逻辑

if (std::is_pointer<T>::value) 
    { 
     delete this->data; 
    } 

编译;行

 delete this->data; 

无论用于实例Node类型。

您必须使用不同的东西。例如:

template <typename T> struct Deleter 
{ 
    static void deleteObject(T) { /* Do nothing */ } 
}; 

template <typename T> struct Deleter<T*> 
{ 
    static void deleteObject(T* obj) { delete obj; } 
}; 

template <class T> 
Node<T>::~Node() 
{ 
    Deleter<T>::deleteObject(data); 
}