C ++:关于内存管理

时间:2011-12-20 13:26:52

标签: c++ memory memory-management memory-leaks

我对C ++有点新,到目前为止一直在使用Obj-C和Java进行编程。

说,我有一个班级:

class Person {

private:
   Wife *current_wife;
   //.....
};

所以obv我需要实现一个setter方法来改变Wife实例变量。

像这样:

Person::SetCurrentWife (Wife *new_wife) {

    current_wife = new_wife;
}

那将是一个副本。

所以从主循环或我称之为的地方:

Person *some_person = new Person();
...
Wife *wife = new Wife ();
some_person->SetCurrentWife(wife);

所以我很困惑:这里会有内存泄漏吗?我应该在这里或在Person的析构函数中删除妻子对象吗?在Obj-C中,我会释放当前的妻子,然后向上面的妻子对象发送一条保留消息,但在C ++中使用setter方法的正确方法是什么?

3 个答案:

答案 0 :(得分:7)

这取决于你想要做什么。首先,正如Kerrek SB所做的那样 注释,如果值语义可以,你不想使用指针 apply:如果Wife是可复制和可分配的,那么几乎没有理由 动态分配它。然而,在这种情况下,我猜测 Wife来自Person(虽然可能是Person的装饰者 因为给定Person是A的事实会更合适 Wife可以随时间变化),甚至可能有派生类型 来自Wife(而Person::current_wife可能希望拥有其中一个 这些),事实上,Wife具有同一性;你不想要副本 到处都是同一个妻子。

如果是这种情况,那么你真的必须为该协议定义一个协议 其他类与Wife的互动。通常,寿命 Wife不会依赖持有它的Person(尽管它是一个。{1}} 装饰者,它可能),所以Person应该只是一个指向它的指针,如 你做完了最有可能的是,Wife对象将具有各种功能 它隐含地或明确地控制了它的生命:你 可能有类似的东西:

void Wife::die()
{
    //  ...
    delete this;
}
例如,

。但是,在这种情况下,任何与Wife结婚的人都会 必须得到通知,以便current_wife不会指向死亡 伴侣。通常,观察者模式的一些变体可用于 这个。 (请注意,Java中存在完全相同的问题;您没有 希望Person::current_wife指向死亡Wife。所以你还是 需要Wife::die()函数和观察者模式来通知 配偶。)

在这种情况下(根据我的经验,这代表了绝大多数 在C ++中动态分配的对象),关于唯一的区别 C ++和Java之间的关系是C ++有一个特殊的语法来调用 “析构函数”;在Java中,您使用通常的函数调用 语法,你可以给你的功能任何你想要的名称(虽然 dispose似乎被广泛使用)。特殊语法允许编译器 生成额外的代码来释放内存,但所有其他代码 与对象生命周期结束相关的活动仍然必须 编程(在析构函数中,在C ++中 - 尽管在这种情况下,它 把它们中的一些直接放在Wife::die中可能是有意义的 功能)。

答案 1 :(得分:4)

你应该使用智能指针。

如果您使用常规指针,请务必小心!

您应该在析构函数和set方法上delete旧的current_wife成员。设置一个新的妻子将导致旧的内存泄漏,因为指向该分配的内存的指针丢失(除非您管理类外的内存 - 见下文)。

但即使这样做,您也需要确保班级以外的任何人都不能删除该成员。您必须决定是将内存管理留给类还是分配到类的外部,并坚持使用它。

答案 2 :(得分:1)

智能指针可以帮助您

using boost::shared_ptr; // or std::shared_ptr, or std::tr1::shared_ptr or something like this
class Person { 

private: 
   shared_ptr<Wife> current_wife; 
   //..... 
}; 

Person::SetCurrentWife (shared_ptr<Wife> new_wife) { 

    current_wife = new_wife; 
} 

现在你不应该删除任何妻子。

shared_ptr<Person> some_person ( new Person );
...  
shared_ptr<Wife> wife ( new Wife );  
some_person->SetCurrentWife(wife);