这个类的析构函数看起来像什么?

时间:2010-04-26 18:54:56

标签: c++

class Equipment
{
    std::vector<Armor*> vEquip;
    Weapon* mainWeapon;
    int totalDefense;
    int totalAttack;

public:

    unsigned int GetWeight();

    int * GetDefense();

    bool EquipArmor(Armor* armor);
    bool UnequipArmor(Armor* armor);

    bool EquipWeapon(Weapon* wep);
    bool UnequipWeapon(Weapon* wep);

    Equipment();
    virtual ~Equipment();
};

似乎应该没有析构函数。指针向量在超出范围时将自行处理,指针指向的实际对象不需要删除,因为会有其他引用。

此处的所有对象都指向主容器:

class Container
{
    int weightLimit;
    unsigned int currWeight;
    std::vector<Item*> vItems;

public:

    bool AddItem(Item* item);
    bool RemoveItem(Item* item);

    Container();
    Container(int weightLim);
    Container(int weightLim, std::vector<Item*> items);
    ~Container();
};

现在我可以看到有必要删除容器中的所有对象,因为这是通过AddItem分配所有对象的地方(新项目(“Blah”))

(护甲和武器继承自物品)

5 个答案:

答案 0 :(得分:1)

如果您需要删除这些项目,请:

Container :: ~Container() {
   for ( unsigned int i = 0; i < vItems.size(); ++i ) {
      delete vItems[i];
   }
}

请注意,要使其正常工作,如果数组确实包含指向Armor和Weapon实例的指针,则Item类必须具有虚拟析构函数。

答案 1 :(得分:1)

非指针类型将自行处理。因此,整数,浮点数,对象等将自行处理,您不必担心删除它们。

该类管理的任何指针都需要被该类的析构函数删除。因此,如果指针指向的内存是在类中分配的,或者如果它被赋予该类,并认为该类将管理它,那么析构函数需要删除指针。

如果指针指向另一个类正在管理的内存,那么你显然不希望析构函数删除它。这是该类的工作,负责该指针所指向的内存。

标准容器管理它们持有指针的指针。所以,如果你有一个指针容器,无论哪个类应该管理它们都需要删除它们。可能性就是容纳容器的类,但这取决于你的代码在做什么。

因此,通常,对于具有指针容器的类,在析构函数中需要这样的东西:

for(containerType<T*>::iterator iter = container.begin(),
                                end  = container.end();
    iter != end;
    ++iter)
{
    delete *iter;
}

每个分配给它的内存的指针都必须有一些东西(通常是一个类,但有时候是分配它的函数),它有效地拥有了那个内存,并确保它被释放。在谈论类时,通常是分配内存的类,但当然,一个类或函数很可能分配内存,然后有效地将该内存的所有权传递给另一个类或函数。无论如何,任何“拥有”记忆的人都需要处理清理它。这就是你的析构函数需要担心的事情:清理该类拥有的任何资源。

答案 2 :(得分:0)

如果我理解正确,您问的是如何从主容器析构函数中的vItems向量中删除项目?

for(std::vector<Item*>::iterator i=vItems.begin(),ie=vItems.end();i!=ie;++i)
    delete *i;

这就是你要求的吗?

答案 3 :(得分:0)

如果你的载体是

std::vector<std::tr1::shared_ptr<Item> >

,那么你就不需要析构函数了。就像现在一样,析构函数必须迭代向量以删除所有项目。最简单的BOOST_FOREACH。

答案 4 :(得分:-1)

这取决于你如何实现它。如果您添加的项目是从对象外部管理的(即addItem()的主体看起来像这样:{ vItems.push_back(items); }),那么您将不需要该析构函数。但是,如果项目由对象管理(即addItem()如下所示:{ vItems.push_back(new Item(item)); },那么您将需要删除析构函数中的所有项目,因为没有人会为您执行此操作。