检查和删除预期
问题描述:
我有一个模板类不工作检查和删除预期
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的内部,我离开了,因为它不是完全有必要帮助回答这个问题。我不确定为什么会出现这个错误,因为我在尝试删除它之前已经确认数据是指针。
有人能让我进一步了解为什么这不起作用/替代方法? (注:不能使用智能指针这个任务)
答
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
答
不能使用逻辑
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);
}
'删除这个 - >数据;' - '数据'是一个'int'。你为什么要“删除”它?包含的'Node'是应该删除的内容(事实上,正如此,否则你的析构函数将不会被触发)。如果你试图取消那些不是指针的东西的资格,那么代码本身应该被SFINAE或专业化的东西忽略掉;不在运行时的if块中。 –
WhozCraig
你为什么要删除'data'开头?不要管它。如果数据是动态分配的,你的班级不应该有任何想法。一个指针不需要用'new'分配,所以你的指针检查甚至不被保证。 – PaulMcKenzie
驱动程序的其他部分使用其他元素,如int *,Card *(自定义类)和其他一些元素。这些数据不会被空的构造函数删除,我不知道如何适当释放内存。我知道数据是一个整数,因此if语句应该失败并且不做任何事情。它应该只反应,当我得到一个实际的指针作为类型(节点例如) –
ZeldaZach