在Polymorph设计上使用数组

时间:2013-09-04 12:33:52

标签: c++ arrays polymorphism

我刚刚开始真正理解多态性,但这对我来说仍然是一个新话题。 所以这是我的问题:我必须上课,敌人和Bankrobber。然而,Bankrobber继承自 敌人。我试图组建一个10名Bankrobbers。然后全局函数应该使用数组的所有成员来做某事,我想这是一个毫无价值的描述,所以这里是代码:

void UpdateEnemies(Enemy * p_Enemy, int counter) { 
    for(unsigned int i = 0;i < counter;i++) { 
        p_Enemy[i].Update(); 
    } 
}

int main(void) { 
    BankRobber EnemyArray[10]; 
    Enemy * p_Enemy = new BankRobber(13,1); 
    UpdateEnemies(EnemyArray,10); 
    system("PAUSE"); 
};   

我为任何语言错误道歉。我不是母语人士

我的实际问题:此代码仅用于练习,因此目的只是在控制台上看到10次更新,对于Array的每个成员。所以函数UpdateEnemys应该调用所有的enemy.update函数。类型转换的方法并不是我想要的,因为它不再是动态的,因为稍后会有更多的敌人。不仅是银行家。

3 个答案:

答案 0 :(得分:2)

多态性仅适用于单个对象,由引用或指向基类的指针访问。它不适用于对象的数组:要访问数组元素,必须知道元素大小,如果你有一个指向基类的指针,情况就不是这样了。

你需要一个额外的间接级别:一个指向单个对象的指针数组,沿着

行。
void UpdateEnemies(Enemy ** p_Enemy, int counter) { 
    for(unsigned int i = 0;i < counter;i++) { 
        p_Enemy[i]->Update(); 
    } 
}

int main() {
    // An array of Enemy base-class pointers
    Enemy * EnemyArray[10]; 

    // Populate with pointers to concrete Enemy types
    for (unsigned i = 0; i < 9; ++i) {
         EnemyArray[i] = new BankRobber;
    }

    // Of course, the array can contain pointers to different Enemy types
    EnemyArray[9] = new Dragon;

    // The function can act polymorphically on these
    UpdateEnemies(EnemyArray,10);

    // Don't forget to delete them. Enemy must have a virtual destructor.
    for (unsigned i = 0; i < 10; ++i) {
         delete EnemyArray[i];
    }
}

您还应该考虑使用RAII类型(如容器和智能指针)来管理这些动态资源;但这超出了这个问题的范围。

答案 1 :(得分:1)

像这样声明一个BankRobber数组

BankRobber EnemyArray[10];

但是比通过像这个

这样的基类指针来访问它们
Enemy * p_Enemy;    
p_Enemy[i].Update();

不行。这是因为索引数组p_Enemy[i]将通过使用offcet sizeof(Enemy)来完成 但是sizeof(BankRobber)可能比sizeof(Enemy)更大,所以p_Enemy [i]最终会出错在错误的地方

您应该使用指针向量,例如

std::vector<Enemy*>

这样,如果将指向不同对象的指针添加到向量中,也可以使用多态。而且你不需要传递丑陋的int counter

答案 2 :(得分:0)

确实你没有确切地说出问题所在。

您是否尝试在代码中进行转换?类似的东西:

void UpdateEnemies(Enemy * p_Enemy, int counter) { 
    BankRobber *pRobber = (BankRobber*)p_Enemy;
    for(unsigned int i = 0;i < counter;i++) { 
        pRobber[i].Update(); 
    } 
}