我正在实现标准模板树结构,我遇到了小问题。
想法每个节点将保存指向某些数据的指针。后来为了正确删除元素,我需要知道它是单个指针还是指向数组的指针。
在我的tree->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;
}
}
在节点初始化期间已设置_destructionMethod
。
有没有什么办法可以选择正确的析构函数而不在初始化期间为它预定义特殊变量?
谢谢!
答案 0 :(得分:4)
第一个基本:
使用delete
分配内存时使用 new
:
int *p = new int;
int *a = new int[10];
//...
delete p;
delete []a; //note the difference!
使用free
分配内存时使用 malloc
:
int *p = (int*)malloc(sizeof(int) * 1);
int *a = (int*)malloc(sizeof(int) * 10);
//...
free(p);
free(a); //no difference!
现在你的问题:
有没有什么方法可以选择正确的析构函数,而不会在初始化期间为它定义特殊变量
考虑policy-based design。这意味着,编写将allocator
封装在一个类中的分配和释放,并在代码中一致地使用它。
答案 1 :(得分:2)
不,没有可移植的方法来找出特定指针最初来自哪个分配器。
答案 2 :(得分:2)
没有办法询问指针以找出它是如何分配的,但一个常见的习惯用法是让分配的对象本身对其自身的破坏负责。看起来你的对象类型并不是所有的类类型,所以你需要将它们包装起来才能做到这一点。例如:
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_;}
};
......等等。
答案 3 :(得分:1)
根本不要这样做。使用智能指针,如C ++ 0x或Boost中的shared_ptr
,或者如果不是选项,则使用C ++中的auto_ptr
。如果您可以有多个对象,请考虑使用std::vector
。
手动资源管理很混乱,很难做到正确。
答案 4 :(得分:0)
也许更好的设计是实现容器使用的抽象接口,其中包含三个具体的子类,这些子类知道它们指向的是什么类型的东西。你的容器只会调用基类中的destroy()方法,让派生类担心调用正确的析构函数。