2013-02-05 45 views
0

我想从基类中创建派生对象的向量。基类中的访问派生类

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

您应该使用'dynamic_cast <>' –

+3

由于[slicing](http://stackoverflow.com/q/274626/50079),您不会使用'vector '去任何地方。 'vector >'是不错的选择。 – Jon

回答

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在工作,所以我不能检查代码,看起来rightish寿= d

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的子类。

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

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; 
    } 
}; 

玩得开心。