Ran*_*dom 12 c++ memory memory-leaks memory-management
我对C++有点新,到目前为止一直在用Obj-C和Java编程.
说,我有一节课:
class Person {
private:
Wife *current_wife;
//.....
};
Run Code Online (Sandbox Code Playgroud)
所以我需要实现一个setter方法来改变Wife实例变量.
像这样:
Person::SetCurrentWife (Wife *new_wife) {
current_wife = new_wife;
}
Run Code Online (Sandbox Code Playgroud)
这将是一个副本.
所以从主循环或我调用的东西:
Person *some_person = new Person();
...
Wife *wife = new Wife ();
some_person->SetCurrentWife(wife);
Run Code Online (Sandbox Code Playgroud)
所以我很困惑:这里会有内存泄漏吗?我应该在这里或在Person的析构函数中删除妻子对象吗?在Obj-C中,我会释放当前的妻子,然后向上面的妻子对象发送一条保留消息,但在C++中使用setter方法的正确方法是什么?
这取决于你想要做什么.首先,正如Kerrek SB所评论的那样,如果可以应用值语义,则不希望使用指针:如果Wife是可复制和可分配的,则几乎没有理由动态分配它.然而,在这种情况下,我猜测它
Wife派生自Person(虽然可能是装饰器Person
更合适,因为给定的PersonisA
Wife可以随时间变化),甚至可能有类型派生Wife(并且Person::current_wife可能需要持有其中一个),事实上,它Wife具有身份; 你不希望到处都是同一个妻子的副本.
如果是这种情况,那么你真的必须为其他类的交互定义一个协议Wife.通常情况下,生命周期
Wife不会取决于Person谁持有它(虽然如果它是装饰器,它可能),所以Person应该只是按住指针,就像你做的那样.最有可能的是,该Wife对象将具有各种功能 - 隐式或显式地控制其生命周期:您可能具有以下内容:
void Wife::die()
{
// ...
delete this;
}
Run Code Online (Sandbox Code Playgroud)
例如.但是,在这种情况下,无论谁结婚Wife都必须得到通知,这样current_wife就不会指向死去的配偶.通常,观察者模式的一些变体可用于此.(请注意,在Java中你有完全相同的问题;你不想Person::current_wife指向一个死的Wife.所以你仍然需要一个Wife::die()函数,以及观察者模式来通知配偶.)
在这种情况下(根据我的经验,它代表了C++中绝大多数动态分配的对象),关于C++和Java之间的唯一区别是C++有一个特殊的语法来调用"析构函数"; 在Java中,您使用通常的函数调用语法,并且您可以为函数指定任何您想要的名称(虽然
dispose似乎被广泛使用).特殊语法允许编译器生成额外的代码来释放内存,但是与对象生命周期结束相关的所有其他活动仍然需要编程(在析构函数中,在C++中 - 尽管在这种情况下,它可能会感觉把它们中的一些直接放在Wife::die
函数中).
您应该使用智能指针。
如果您使用常规指针,请务必小心!
您应该在析构函数和 set 方法上使用delete旧成员。current_wife设置新妻子将导致旧妻子的内存泄漏,因为指向分配的内存的指针丢失(除非您在类之外管理内存 - 见下文)。
但即使这样做,您也需要确保类之外的任何人都无法删除该成员。您必须决定是将内存管理留给类还是分派到类外部,并坚持下去。
| 归档时间: |
|
| 查看次数: |
831 次 |
| 最近记录: |