C++ 动态转换

标签 c++ inheritance dynamic polymorphism

我有一个主抽象类,我必须基于这个类创建子类(不能修改):

class Spaceship
{
  protected:
    string m_name;      // the name of the ship
    int m_hull;         // the hull strenght
  public:

    // Purpose: Default Constructor
    // Postconditions: name and hull strength set to parameters
    // -- INLINE
    Spaceship(string n, int h)
    {
      m_name = n;
      m_hull = h;
    }

    // Purpose: Tells if a ship is alive.
    // Postconditions: 'true' if a ship's hull strength is above zero,
    //                 'false' otherwize.
    // -- INLINE
    bool isAlive()
    {
      return (m_hull > 0);
    }

    // Purpose: Prints the status of a ship.
    // -- VIRTUAL
    virtual void status() const = 0;

    // Purpose: Changes the status of a ship, when hit by a
    //    weapon 's' with power level 'power'
    // -- VIRTUAL
    virtual void hit(weapon s, int power) = 0;

    string getName() const
    {
      return m_name;
    }

}; //Spaceship

我的子类的示例也是如此:

class Dreadnought: public Spaceship
{
  int m_shield;
  int m_armor;
  int m_type;
  public:
    Dreadnought( string n, int h, int a, int s ): Spaceship( n, h ),m_shield( s ),m_armor(a),m_type(dreadnought){}
    virtual void status() const
    {
      // implementation not shown to save space
    }
    virtual void hit(weapon s, int power)
    {
      // implementation not shown to save space
    }

    int typeOf(){ return m_type; }
};

在我的主要代码中,我有一个不同类型宇宙飞船的动态数组:

Spaceship ** ships;

cin >> numShips;

// create an array of the ships to test
ships = new Spaceship * [numShips];

然后我从用户那里得到输入来在这个数组中声明不同类型的船,比如:

ships[0] = new Dreadnought( name, hull, armor, shield );

我的问题是,当我去删除数组时,没有调用正确的析构函数,而是调用了 Spaceships,这是否会造成内存泄漏,因为成员变量“m_shield、m_armor”没有被删除并悬空?如果是这样,是否有比使用 var m_type 和调用更好的方法来获取类型:

if( ships[i]->typeOf() == 0 )
      delete dynamic_cast<Frigate*>(ships[i]);
    else if( ships[i]->typeOf() == 1 )
      delete dynamic_cast<Destroyer*>(ships[i]);
    else if( ships[i]->typeOf() == 2 )
      delete dynamic_cast<Battlecruiser*>(ships[i]);
    else if( ships[i]->typeOf() == 3 )
      delete dynamic_cast<Dreadnought*>(ships[i]);
    else
      delete dynamic_cast<Dropship*>(ships[i]);

我声明的 Spaceship 类中的问题 #2:virtual int typeOf() = 0;并将其注释掉,有没有一种方法可以在子类中实现此功能而无需在父类中声明,以便我可以像上面所示那样使用它?当我不声明它时,我得到编译器错误:

错误:'class Spaceship' 没有名为'typeOf' 的成员

我假设这又与动态大小写有关。

任何帮助都会很棒,

谢谢 自然

编辑:

为了澄清我的第一个问题,如果我这样做,我会不会有内存泄漏:

删除船只[i];

或者我应该这样做:

删除 dynamic_cast(ships[i]);

删除仅在派生类中的成员变量?

谢谢

最佳答案

您必须向您的 Spaceship 类添加一个虚拟析构函数。然后 delete 将正确地销毁数组中的元素。

您必须在 Spaceship 中声明 typeOf() 方法。否则,编译器无法知道这是一个有效的成员函数。

如果您在基类中将所需功能作为虚拟成员函数添加,则可以避免 typeOf()

即使您出于某种原因不能修改您的基类,您也可以执行dynamic_cast 并测试它是否产生空指针

Frigate *p = dynamic_cast<Frigate*>(ships[i]);
if (p != 0) {
    // do something with a frigate
}

关于C++ 动态转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15304179/

相关文章:

c# - 使用动态是否被认为是一种不好的做法?

c++ - 查找所有子字符串的出现和位置

c++ - 如何在黑莓级联中创建用于json解析的 ListView

inheritance - 组合和多重继承

c# - 尊重派生属性类型的 AttributeUsage

ios - ObjC-以编程方式将标签添加到UIScrollView

java - 如何使用 Selenium Webdriver 和 Java 单击同一行中的旁边/上一个表格单元格 (TD)?

c++ - 在 Eclipse CDT 中构建 OpenFrameWorks 项目时 Raspberry Pi 崩溃

c++ - 多线程和多进程应用程序的锁定机制有什么区别?

java - 从类型参数扩展