从基类访问派生类

时间:2013-02-05 23:54:28

标签: c++

我正在尝试从其基类中创建派生对象的向量。

class Animal
{
 // Do Stuff
}

class Dog : public Animal

{
 // Do Stuff
}

class AnimalKingdom
{
    vector<Animal> animals;
    vector<Dog> getDogs();
}

vector<Dog> AnimalKingdom::getDogs();
{

    vector<Dog*> dogs;        

    for(i = 0; i < animals.size(); i++)
    {
        Animal& a = *animals[i];

        if(typeid(a).name() == "class Dog")
        {
            dogs.push_back(*a);
        }
    }
}

但显然* a不是指向狗的指针,所以它不能添加到狗身上?

这有意义吗?

3 个答案:

答案 0 :(得分:0)

您需要将强制动物类型输入狗中。做一些关于static_cast和dynamic_cast的阅读。但一般来说static_cast就是你知道你要转换成什么类型​​,而dynamic_cast是一个猜测,如果它不是那个类型,它将返回null。

for(i = 0; i < animals.size(); i++)
{
    Animal* a = &animals[i];

    if(typeid(a).name() == "class Dog")
    {
        dogs.push_back(static_cast<Dog>(a));
    }
}

Ps.Im正在工作,所以我无法检查该代码,看起来很正确tho = D

答案 1 :(得分:0)

首先,typeid(a).name()将返回编译器特定的字符串。例如,在我的gcc中,返回的字符串将完全不同。另外,想想第三类是Dog的子类。你的typeid(a).name()会给你“奇瓦瓦级”,这是一只狗,但不是“阶级狗”。

您应该使用dynamic_cast查询对象类型。当你dynamic_cast<Dog*>(a)时,你会问“可以正确地将其投放到狗身上吗?”。如果是,您将有一个Dog *类型的指针,如果没有,您将有一个NULL指针。

最后,在class AnimalKingdom,你的矢量不允许你拥有Dog类型的对象。创建std::vector<Animal>时,您将创建一个元素具有固定类型sizeof(Animal)的向量。您需要的是使用指针。指针指向一个内存地址,而不强制该地址为任何大小或基类。

只是为了更清楚一点:执行Animal a;时,您创建的变量类型为Animal且大小为sizeof(Animal)。执行Animal* a时,您正在创建一个大小为4字节(或8字节)的内存地址,对于任何具有此大小的指针。因此,Animal *可能指向与Animal不同的东西,它可能指向Animal的子类。

这是静态分配(固定大小)和动态分配(动态大小,但请注意指针具有固定大小)之间的区别。

答案 2 :(得分:0)

你的主要问题是理解你不能向上转换,这会产生null。你可以将狗垂头转向动物,但只使用父母的最小属性,

所以这个问题很容易解决,如: 1-返回向量并使用多态流来做任何你想要的事情。 2-制作一些bool或int来检查或标记下面的动物种类。例如为狗做2,这个变量在动物类中定义。然后使用虚函数动态地在运行时转到任何你想要的东西。所以下面的代码可以成为你的好骨架。

class Animal
{
    int type;
    virtual void setType()=0;
    virtual int getType()=0;
};

class Dog :public Animal
{
    void setType()
    {
        type = 2;
    }
    int gettype()
    {
        return type;
    }
}; 

玩得开心。