C++ 检查和删除未按预期工作

C++ 检查和删除未按预期工作,c++,c++11,C++,C++11,我有一个模板类 template <class T> class Node { private: T data; public: Node<T> *next; Node(T initial); ~Node(); }; 节点是LinkedList的内部,我将其省略,因为不完全需要它来帮助回答这个问题。我不确定为什么会出现此错误,因为在尝试删除数据之前,我进行了检查以确保数据是指针 有

我有一个模板类

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

    public:
        Node<T> *next;
        Node(T initial);
        ~Node();
};    
节点是LinkedList的内部,我将其省略,因为不完全需要它来帮助回答这个问题。我不确定为什么会出现此错误,因为在尝试删除数据之前,我进行了检查以确保数据是指针


有人能进一步告诉我为什么这不起作用/一种替代方法吗?(注意:无法在此分配中使用智能指针)

您不能使用逻辑

    if (std::is_pointer<T>::value)
    {
        delete this->data;
    }
无论用于实例化
节点的类型如何

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

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);
}
模板结构删除器
{
静态void deleteObject(T){/*不执行任何操作*/}
};
模板结构删除器
{
静态void deleteObject(T*obj){delete obj;}
};
样板
节点::~Node()
{
Deleter::deleteObject(数据);
}

如果
语句是在代码中创建运行时分支的工具。不是条件编译。扩展模板代码时,其外观类似于:

Node<int>::~Node()
{
    if (false)
    {
        delete this->data;
    }
}
现在,任何人都希望此代码输出
~A()
。代码也是如此。通常,您希望类型自行管理并释放任何获得的资源。因此,代码中的更改只需删除delete并假定该类型可以自行管理


如果您真的想这样做,我不推荐这样做,您可以这样做:

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);
}
模板
void deleteIfPtr(T*ptr){delete ptr;}
样板
void deleteiftr(const T&){/*否则,不执行任何操作*/}
样板
节点::~Node()
{
删除IFPTR(此->数据);
}

删除此->数据
-
数据
是一个
整数
。你为什么要
删除它?enshrouding
节点
应该被删除(事实上,就是这样,否则你的析构函数不会被触发)。如果您试图取消不是指针的东西的资格,代码本身应该被SFINAE或专门化之类的东西省略;不在运行时if-block中。为什么要首先删除
数据
?别管它。您的类不应该知道数据是否是动态分配的。指针不需要分配
new
,因此您的指针检查甚至没有保证。驱动程序的其他部分使用其他元素,如int*、Card*(自定义类)和其他一些元素。其中的数据不会被空构造函数删除,我不知道如何适当地释放内存。我知道数据是一个int,因此if语句应该失败,并且不会对它做任何处理。只有当我得到一个实际指针作为我删除答案的类型(例如节点)时,它才会做出反应,因为它只向您展示了如何消除编译错误,但正如其他人所建议的那样,这不是一种正确的方法@泽尔达扎奇——如果你有指针,那么同样,你的类不应该在意。如果用户希望向类引入指针,那么用户负责清理内存。如果您想要一个具体的示例,请查看STL类,例如
std::vector
std::list
。如果用户想要创建
std::vector
,那么他们放入vector的
卡*
是用户的责任,而不是
vector
。模板类不应该知道或关心指针来自何处。模板类关心的只是维护其数据所需的内存,而不是其他。我决定使用unique_ptr,感谢您的帮助!
        delete this->data;
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);
}
Node<int>::~Node()
{
    if (false)
    {
        delete this->data;
    }
}
struct A { ~A() { std::cout << "~A()" << std::endl; } };

auto a = new A;

std::vector<A*> vec;

vec.emplace_back(a);

vec.clear();
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();
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);
}