对象数组(基本情况)和派生类之间的动态转换

Posted

技术标签:

【中文标题】对象数组(基本情况)和派生类之间的动态转换【英文标题】:Dynamic casting between array of objects(base case) and a derived class 【发布时间】:2015-04-13 15:38:33 【问题描述】:

我有一个对象数组,其类是基类,数组的元素是派生类。

    Object *object [kNumPlayers] =
   
        new Human ("Ms. Jones", 50, 1.0f, 2.0f),
        new Alien ("Mx. Charm", 70),
        new Human,
        new Alien,
   ;

所以这里,Object 是基类,Human 和 Alien 是派生类。现在我的问题是我需要访问每个对象并添加额外的功能。如中,我需要访问对象 [0](即人类)并添加需要添加的任何内容。所以我尝试了,

   Human human0 = (Human)object[0]; // ERROR:'no matching function to call                  Human::Human(Object*&)'
                        OR
   Human *human0;
   human0 = dynamic_cast<Human*>(object[0]); //ERROR: cannot dynamic_cast 'object[0]' (of type 'class Oject*') to type 'class Human*' (source is not polymorphic)'

【问题讨论】:

你的基类至少需要一个虚函数。 使用原始指针你应该写Human* human0 = (Human*)object[0]; 我如何访问 Human 类中的 object[0]?如果我有 2 个对象说,Human* human0 = (Human*)object[0];Human* human1 = (Human*)object[1],那么我该怎么说“如果(对象 [0])然后 - “这是我想做的事情” 【参考方案1】:

要编译dynamic_cast,规则是源必须是多态类——这意味着它必须至少有一个virtual函数,即使它只是析构函数。在您的情况下,源类是 Object 类,它必须是多态的:

class Object

   public:
     virtual ~Object() = default; //at least, it should be virtual
     //etc
;

一旦你修复了代码至少应该编译。但是,在 C++ 中你应该避免使用很多东西:

避免使用 C 样式数组(动态或其他) 首选std::vectorstd::array。 避免自己管理内存——也就是说,避免使用裸new。 首选 RAII - 在您的情况下,使用适合您需要的 std::unique_ptrstd::shared_ptr

那就是你应该是这样的:

 std::array<std::shared_ptr<Object>, 10> objects 
        std::make_shared<Human>("Ms. Jones", 50, 1.0f, 2.0f),
        std::make_shared<Alien>("Mx. Charm", 70)
        //etc
 ;

并转换为:

 std::shared_ptr<Human> human = std::dynamic_pointer_cast<Human>(objects[0]);

希望对您有所帮助。

【讨论】:

以上是关于对象数组(基本情况)和派生类之间的动态转换的主要内容,如果未能解决你的问题,请参考以下文章

使用反射用基类数组填充派生类数组

如何以多态方式创建对象的动态数组?

使用具有指向派生类对象的指针的基类指针数组调用派生类方法

关于C++基类、派生类的引用和指针

为啥派生类对象的指针数组无法声明

C# 对象文件与二进制串(byte数组)之间的转换