我正在编写一个模板类,它以指针作为输入并存储它。该指针指向由另一个类分配的对象,并交给包含该类的指针。
现在我想为这个容器创建一个析构函数。我应该如何释放该指针指向的内存?我无法事先知道它是数组还是单个元素。
我对C ++还比较新,请见谅。我一直在使用C,Java是我选择的面向对象语言,但由于想要学习C ++和项目的速度要求,我选择了C ++。
将容器从模板更改为抽象类的容器,可以实现自己的析构函数,这是一个更好的主意吗?
我正在编写一个模板类,它以指针作为输入并存储它。该指针指向由另一个类分配的对象,并交给包含该类的指针。
现在我想为这个容器创建一个析构函数。我应该如何释放该指针指向的内存?我无法事先知道它是数组还是单个元素。
我对C ++还比较新,请见谅。我一直在使用C,Java是我选择的面向对象语言,但由于想要学习C ++和项目的速度要求,我选择了C ++。
将容器从模板更改为抽象类的容器,可以实现自己的析构函数,这是一个更好的主意吗?
new
或者 new[]
进行了分配,那么删除它是不安全的。// by luck, this works on my preferred platform
// don't do this - just an example of why your code seems to work
int *ints = new int[20];
delete ints;
但是你可以这样做:
// crashes on my platform
std::string *strings = new std::string[10];
delete strings;
int
没有析构函数。 - Steven Suditnew
和 delete
会导致未定义的行为,即使类型有一个平凡的析构函数也是如此。我完全可以根据需要替换 operator new
和 operator delete
;而且我可以期望我的 delete
函数中的指针已经是对应的 new
输出的。 - GManNickG您必须记录该类的使用方式,并按预期分配。您还可以向对象传递标志,指定它应如何销毁。此外,请查看boost的智能指针,它可以为您处理此区别。
free()
必须与malloc()
匹配(而free()
本身无法检查),例如std::auto_ptr<X>
必须与new
匹配。- 我不会担心标志,为什么应该在运行时做出释放例程的决定,如果new
与new[]
的使用将在编译时完成呢? - UncleBens简短回答:
如果您在new中使用[],则在delete中也要使用[]。
//allocate some memory
myObject* m = new myObject[100];
//later on...destructor...
delete m; //wrong
delete[] m; //correct
new
的类也应该调用delete
。std::auto_ptr<int> ap(new int()); boost::shared_ptr<int> sp(new int());
两者都会为您调用delete。 - Roger Pate你根本不应该删除它。如果你的类使用一个已经初始化的指针,那么删除它是不安全的。它甚至可能不指向堆上的对象;调用delete
或delete[]
都可能导致灾难性后果。
内存的分配和释放应该在同一作用域内进行。无论哪段代码拥有并初始化了你的类实例,也应该负责初始化并传递指针,而那里才是你应该使用delete
的地方。
new
进行内存分配,使用delete
释放。new[]
进行内存分配,使用delete[]
释放。如果在这些语句之后仍然存在问题(也许您想删除由其他人创建的对象),那么您正在违反第三条规则:
(按照要求将我的评论转化为答案。)
JonH的答案是正确的(关于只在使用数组构造时使用数组解构),因此也许您应该提供模板:一个用于数组,另一个不用。
另一个答案是避免使用数组,而是期望一个可能是适当的集合并在自身清理的单个实例,例如vector<>。
编辑
从Roger Pate大胆盗取,我将补充说,您可以要求使用智能指针,这相当于单个项目集合。
delete
,则对于大多数用途而言,它与选项1同样易于使用)。现在,如果有人想给该类一个指向静态分配对象的指针,则可以传递一个空操作函数对象,这样当类想要释放它时,什么也不会发生;或者传递一个执行new[]
分配的对象的delete[]
操作的函数对象等。由于C++中的指针无法告诉我们它是如何分配的,所以没有办法决定使用哪种释放方法。解决方案是将选择权交给用户,希望用户知道内存是如何分配的。请查看Boost smart ptr库,特别是shared_ptr构造函数的第二个参数,这是一个很好的例子。
delete
,所以不要给我数组”,而不是试图让它同时适用于两种情况。理想情况下,人们应该使用vector
而不是原始内存数组。 - GManNickG