如何删除在函数参数上声明的新指针? [英] How to delete new pointer that declared on function parameters?

查看:206
本文介绍了如何删除在函数参数上声明的新指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的类具有成员函数,该成员函数以其自身类型的指针作为参数.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆