如何从基类动态创建和使用派生类?

Posted

技术标签:

【中文标题】如何从基类动态创建和使用派生类?【英文标题】:How to dynamically create and use a derived class from a base class? 【发布时间】:2018-09-05 22:11:16 【问题描述】:

我想使用指向父类的指针来分配和使用子类对象。我有一个带有子 Dog 类的 Animal 类,Assign 类应该将 Dog 类添加到它的 Animal 指针数组 (Animal**animals)。目前cout<<animals[0]->weight 输出正确,但animals[0]->breed 给出错误:Class 'Animal' has no member named 'breed'。我必须这样做,因为这是为了实用(这也是一个简化的示例,因为在真实示例中,我们将拥有一组 Animal/派生的 Animal 对象)。代码如下:

#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

class Animal
public:
  double weight;
  Animal(double w)
    weight=w;
  
  void shout()
    cout<<"Weight: "<<weight<<endl;
  
;

class Dog: public Animal
public:
  string breed;
  Dog(string b,double w): Animal(w)
    breed=b;
    weight=w;
  
;

class Asign
public:
  Animal**animals;
  Asign()
    animals=new Animal*[2];
    animals[0]=new Dog("Great Dane",12.2);
    cout<<animals[0]->breed<<endl;//Does not work
  
;

int main()
  Dog Duke("Great dane",12.2);
  Asign a;

【问题讨论】:

每个Animal 都应该有一个breed 吗?如果是这样,那么Animal 类应该有一个breed 成员。如果不是,那么animals[0]-&gt;breed 是不明智的,因为不是每个Animal 都有breed,所以没有办法从Animal 获得breed。哎呀,谁知道它是什么类型的? Cat 可以从 Animal 派生而来,并且有一个 int 称为 breed 编译器知道的所有内容。 【参考方案1】:

Animal(基类)没有breed 成员变量,因此您收到错误消息。即使Dog 有一个品种成员变量,Animal 对此一无所知。正确的代码是使用dynamic_castAnimal 指针转换为Dog 以向下转换类层次结构,然后您将可以访问类成员:

cout<<dynamic_cast<Dog*>(animals[0])->breed<<endl;

请注意,在使用 dynamic_cast 返回的指针之前检查它是否不是 NULL 的好习惯,因为如果转换失败,它可以返回 NULL

【讨论】:

使用dynamic_cast时,请务必在使用指针前检查返回值是否为NULL,例如:Dog *d = dynamic_cast&lt;Dog*&gt;(animals[0]); if (d) cout &lt;&lt; d-&gt;breed &lt;&lt; endl; else /* not a Dog, do something else */ Animal 转换到Dog 会是向下转换,而不是向上转换,对吧?

以上是关于如何从基类动态创建和使用派生类?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C++ 中的模板编程从基类创建派生类?

如何通过派生类函数从基类更改向量

如何从基类中获取派生类名

如何从现有的基类对象创建派生类对象?

如何使用多态性从基类访问派生类向量成员?

如何在没有虚方法的情况下创建派生类的基类?