【问题标题】:What would the destructor for this class look like?这个类的析构函数会是什么样子?
【发布时间】:2010-04-27 03:11:26
【问题描述】:
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(new Item("Blah")) 分配所有对象的地方

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

【问题讨论】:

  • 1. “会有其他的参考。”那么其他引用的所有者如何知道何时可以安全地删除对象呢?
  • mainWeapon 是 C++ 指针(相对于更智能的指针)。析构函数应该负责释放。如果您希望指针处理分配和释放,请使用Boost::shared_ptrscoped_ptr。智能指针向量没有问题,但是析构函数应该在销毁向量之前释放向量中所有指针使用的内存。

标签: c++


【解决方案1】:

非指针类型会自行处理。因此,int、float、objects 等会自行处理,您不必担心删除它们。

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

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

如果标准容器持有指针,则管理它们持有的指针。因此,如果您有一个指针容器,则应该管理它们的任何类都需要删除它们。奇怪的是,这是保存容器的类,但这取决于您的代码在做什么。

因此,通常,对于具有指针容器的类,您需要在析构函数中使用类似的内容:

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

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

【讨论】:

    【解决方案2】:

    如果您需要删除项目,那么:

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

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

    【讨论】:

      【解决方案3】:

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

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

      这是你要求的吗?

      【讨论】:

        【解决方案4】:

        如果你的向量是

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

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-02-04
            • 2022-06-11
            • 2015-02-10
            • 1970-01-01
            • 2015-02-04
            • 1970-01-01
            • 2014-04-22
            • 1970-01-01
            相关资源
            最近更新 更多