如何删除在函数参数上声明的新指针? [英] How to delete new pointer that declared on function parameters?
问题描述
我的类具有成员函数,该成员函数以其自身类型的指针作为参数.
My class have member function that take pointer of it's own type as it's argument.
当我这样做时:
Object* obj1 = new Object();
Object* obj2 = new Object();
obj1->add_child(obj2)
delete obj1;
delete obj2;
obj1 = NULL;
obj2 = NULL;
并运行valgrind
,报告显示:
HEAP SUMMARY:
in use at exit: 72,704 bytes in 1 blocks
total heap usage: 6 allocs, 5 frees, 73,098 bytes allocated
LEAK SUMMARY:
definitely lost: 0 bytes in 0 blocks
indirectly lost: 0 bytes in 0 blocks
possibly lost: 0 bytes in 0 blocks
still reachable: 72,704 bytes in 1 blocks
suppressed: 0 bytes in 0 blocks
我阅读了一个答案,说still reachable
很好,没有泄漏.然后,当我尝试这样做时:
I read an answer says that still reachable
is fine, no leak. Then, when I try this:
Object* obj = new Object();
obj1->add_child(new Object());
delete obj;
obj = NULL;
valgrind
的报告说:
HEAP SUMMARY:
in use at exit: 72,877 bytes in 3 blocks
total heap usage: 6 allocs, 3 frees, 73,098 bytes allocated
LEAK SUMMARY:
definitely lost: 144 bytes in 1 blocks
indirectly lost: 29 bytes in 1 blocks
possibly lost: 0 bytes in 0 blocks
still reachable: 72,704 bytes in 1 blocks
suppressed: 0 bytes in 0 blocks
很明显,我没有删除作为参数传递的new Object()
指针.那么,如何删除该指针?
It's obvious that I didn't delete the new Object()
pointer that passed as an argument. So, how do I delete that pointer?
详细更新
add_child(Object* obj)
的定义:
void add_child(Object* obj) {
container.add_child(obj);
}
container
是作为模板类实例的Object
的成员.
container
is a member of Object
which is an instance of template class.
Container<Object> container;
Container
的定义是:
template<class T>
class Container {
public:
void add_child(const std::string& key, T* child) {
childrens.insert(std::pair<std::string,T*>(key, child));
}
private:
std::multimap<std::string,T*> childrens;
}
然后,孩子们实际上是std::multimap
.
Then, the childrens is actually a std::multimap
.
我希望这个问题不会太长,只是一个问题.
I hope this not too long for just a question.
推荐答案
您需要对谁拥有指针的指针做出明确而一致的选择.如果您确定add_child
拥有所有权,则呼叫者应期望他们不需要删除传入的指针.如果您确定add_child
不拥有所有权, ,则调用方保留所有权并删除指针.
You need to make a clear and consistent choice about who owns pointers. If you decide that add_child
takes ownership, then the caller should expect that they don't need to delete the pointer passed in. If you decide that add_child
does not take ownership, then the caller retains ownership and deletes the pointer.
您可以使Object
拥有所有权,因此其析构函数将删除已添加到其中的所有子指针.然后,您的第一个示例应阅读
You can make Object
take ownership, so its destructor deletes all the child pointers that have been added to it. Then your first example should read
Object* obj1 = new Object();
Object* obj2 = new Object();
obj1->add_child(obj2);
delete obj1; // also deletes obj2 automatically
和您的第二个:
Object* obj = new Object();
obj->add_child(new Object());
delete obj; // automatically deletes the unnamed pointer passed in on previous line
如果您不希望Object
拥有所有权,那么您就遇到了问题,因为您无法在调用方的上下文中删除new Object()
.
If you don't want Object
to take ownership, then you have a problem, since you have no way of deleting the new Object()
in the context of the caller.
如果使用智能指针,则所有权管理变得容易得多. add_child
可以接受std::unique_ptr<Object>
自变量.
If you use smart pointers, managing ownership becomes much easier. add_child
can take a std::unique_ptr<Object>
argument.
auto obj1 = std::make_unique<Object>();
auto obj2 = std::make_unique<Object>();
obj1->add_child(std::move(obj2)); // obj1 takes ownership
// both pointers automatically deleted at scope exit
auto obj = std::make_unique<Object>();
obj->add_child(std::make_unique<Object>());
// both pointers automatically deleted at scope exit
这篇关于如何删除在函数参数上声明的新指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!