C++ 删除指针的哪种方式:删除/删除[]/自由?

C++ 删除指针的哪种方式:删除/删除[]/自由?,c++,pointers,C++,Pointers,我正在实现standart模板树结构,遇到了一个小问题 每个节点将持有指向某些数据的指针的想法。稍后为了正确删除元素,我需要知道它是单个指针还是指向数组的指针 在我的树->ReleaseMemory()方法中,我有以下代码: if (node->_data != NULL) { switch (_destructionMethod){ case tree_delete: delete node->_data; br

我正在实现standart模板树结构,遇到了一个小问题

每个节点将持有指向某些数据的指针的想法。稍后为了正确删除元素,我需要知道它是单个指针还是指向数组的指针

在我的
树->ReleaseMemory()方法中,我有以下代码:

if (node->_data != NULL)    {

        switch (_destructionMethod){

        case  tree_delete:
            delete  node->_data; break;
        case  tree_deleteList:
            delete [] node->_data; break;
        case  tree_free:
            free(node->_data); break;

    }


}
其中
\u destructionMethod
已在节点初始化期间设置。 是否有任何方法可以选择正确的析构函数,而无需在初始化过程中为其在特殊变量中预定义它


谢谢

根本不要这样做。使用智能指针,如Cux> SyddYPPT/<代码>,从C++ 0x或Boost或如果不是选项,< C++ >代码> AutoPPTR <代码>。如果可以有多个对象,请考虑使用<代码> STD::vector < /代码> .<
手动资源管理很混乱,很难正确进行

根本不要这样做。使用智能指针,如Cux> SyddYPPT/<代码>,从C++ 0x或Boost或如果不是选项,< C++ >代码> AutoPPTR <代码>。如果可以有多个对象,请考虑使用<代码> STD::vector < /代码> .< 手动资源管理很混乱,很难正确进行

第一基础:

使用
new
分配内存时使用
delete

int *p = new int;
int *a = new int[10];
//...
delete p; 
delete []a; //note the difference!
使用
malloc
分配内存时使用
free

int *p = (int*)malloc(sizeof(int) * 1);
int *a = (int*)malloc(sizeof(int) * 10);
//...
free(p);
free(a); //no difference!

现在你的问题是:

在初始化过程中,我是否可以选择正确的析构函数,而不必在特殊变量中预先定义它

考虑一下。这意味着,编写
分配器
,将分配和解除分配封装在一个类中,并在代码中一致地使用它。

第一个基本:

使用
new
分配内存时使用
delete

int *p = new int;
int *a = new int[10];
//...
delete p; 
delete []a; //note the difference!
使用
malloc
分配内存时使用
free

int *p = (int*)malloc(sizeof(int) * 1);
int *a = (int*)malloc(sizeof(int) * 10);
//...
free(p);
free(a); //no difference!

现在你的问题是:

在初始化过程中,我是否可以选择正确的析构函数,而不必在特殊变量中预先定义它


考虑一下。也就是说,编写一个将分配和释放封装在类中并在代码中一致使用的
allocator

不,没有可移植的方法来找出特定指针最初来自哪个分配器。

不,没有可移植的方法来找出某个特定指针最初来自哪个分配器。

没有方法通过询问指针来找出它是如何分配的,但是一个常见的习惯用法是让分配的对象自己负责自己的破坏。不过,看起来您的对象类型并不是所有的类类型,所以您需要包装它们才能做到这一点。例如:

class destroyable_node
{
    virtual void destroy() = 0;
};

template <typename T> class object_node : public destroyable_node
{
private:
    T * value_;

public:
    // Presumes T is copy-constructable.
    object_node(T value) : value_( new T(value) ) {}

    operator T&() {return value_;}
    operator T const &() const {return value_;}

    void destroy() {delete value_;}
};

template<typename T> class array_node : public destroyable_node
{
private:
    T * value_;

public:
    array_node(T[] value)
        : value_( new T[ sizeof(value)/sizeof(T) ] )
    {
        std::copy(value, value + sizeof(value)/sizeof(T), value_);
    }

    operator T*() {return value_;}
    operator T const *() const {return value_;}

    void destroy() {delete[] value_;}
};
类可销毁_节点
{
虚空销毁()=0;
};
模板类对象\u节点:公共可销毁\u节点
{
私人:
T*值u;
公众:
//假定T是可复制构造的。
对象\节点(T值):值\新的T(值)){
运算符T&({返回值}
运算符T常量&()常量{返回值}
void destroy(){删除值}
};
模板类数组_节点:公共可销毁_节点
{
私人:
T*值u;
公众:
数组_节点(T[]值)
:value_uT(新的[sizeof(value)/sizeof(T)])
{
std::copy(value,value+sizeof(value)/sizeof(T),value_);
}
运算符T*(){返回值}
运算符T常量*()常量{返回值}
void destroy(){delete[]值}
};

…等等。

没有办法通过询问指针来了解它是如何分配的,但是一个常见的习惯用法是让分配的对象自己负责自己的破坏。不过,看起来您的对象类型并不是所有的类类型,所以您需要包装它们才能做到这一点。例如:

class destroyable_node
{
    virtual void destroy() = 0;
};

template <typename T> class object_node : public destroyable_node
{
private:
    T * value_;

public:
    // Presumes T is copy-constructable.
    object_node(T value) : value_( new T(value) ) {}

    operator T&() {return value_;}
    operator T const &() const {return value_;}

    void destroy() {delete value_;}
};

template<typename T> class array_node : public destroyable_node
{
private:
    T * value_;

public:
    array_node(T[] value)
        : value_( new T[ sizeof(value)/sizeof(T) ] )
    {
        std::copy(value, value + sizeof(value)/sizeof(T), value_);
    }

    operator T*() {return value_;}
    operator T const *() const {return value_;}

    void destroy() {delete[] value_;}
};
类可销毁_节点
{
虚空销毁()=0;
};
模板类对象\u节点:公共可销毁\u节点
{
私人:
T*值u;
公众:
//假定T是可复制构造的。
对象\节点(T值):值\新的T(值)){
运算符T&({返回值}
运算符T常量&()常量{返回值}
void destroy(){删除值}
};
模板类数组_节点:公共可销毁_节点
{
私人:
T*值u;
公众:
数组_节点(T[]值)
:value_uT(新的[sizeof(value)/sizeof(T)])
{
std::copy(value,value+sizeof(value)/sizeof(T),value_);
}
运算符T*(){返回值}
运算符T常量*()常量{返回值}
void destroy(){delete[]值}
};

…等等。

也许更好的设计是用三个具体的子类实现容器使用的抽象接口,这些子类知道它们持有指向什么类型的指针。您的容器只需在基类中调用destroy()方法,并让派生类担心调用正确的析构函数。

也许更好的设计是使用三个具体的子类实现容器使用的抽象接口,这些子类知道它们持有指向哪种类型的指针。您的容器只需在基类中调用destroy()方法,并让派生类担心调用正确的析构函数。

尽管这是可能的,但根据情况使用原始指针/数据可能仍然有效。但是如果是这样的话——我认为除非你从一开始就处理分配,否则不应该实现一个发布。注意C++0xC中存在
boost::checked\u array\u deleter
std::default\u delete
,并避免在STL容器中使用std::auto\u ptr:虽然这可能,但使用原始指针/数据仍然有效视情况而定。但是如果是这样的话——我认为除非你从一开始就处理分配,否则不应该实现一个发布。注意C++0xC中存在
boost::checked\u array\u deleter
std::default\u delete
,并避免将std::auto\u ptr与S一起使用