【问题标题】:Is it possible to have an array of different objects that come from the same base class?是否可以拥有来自同一基类的不同对象的数组?
【发布时间】:2010-12-08 03:02:11
【问题描述】:

我正在尝试为游戏设计一个武器类。这是我为满足我的需要而编写的一些代码:

class weapon {

 public:
  int fireRate;
  int bulletDamage;
  int range;
  ofImage sprite;
  ofImage bulletSprite;
  bullet bullets[50];
  int activeBullet;

 public:
  void fire();
};

class machineGun: public weapon {
 public: 
  void fire();
};

class flamer: public weapon {
 public: 
  void fire();
};

然后我想像这样定义一个武器数组:

//Weapon variables
const int totalWeapons = 2;
int currentWeapon = 1;
weapon weapons[totalWeapons];

我希望元素 [0] 代表 machineGun 类,元素 [1] 代表火焰喷射器类。我是否以正确的方式解决这个问题?我应该以某种方式重构它吗?我如何实现拥有这两种不同武器的阵列?

我的想法是,当我调用 weapons[0].fire(); 时,我得到一个 machineGun 类,当我调用 weapons[1].fire(); 时,我得到火焰喷射器。




编辑:感谢大家的帮助。我在使用“weapons[0] = new machineGun;”时遇到了一些问题。当我尝试运行此代码时,出现错误“无法分配常量大小为 0 的数组”。

有没有人知道为什么这不起作用?我更新后的代码如下所示:

//Weapon variables
const int totalWeapons = 2;
int currentWeapon = 1;
weapon weapons[totalWeapons];
weapons[0] = new machineGun;
weapons[1] = new flamer;

但我得到了很多错误:

1>gameplay.cpp(49) : error C2466: cannot allocate an array of constant size 0
1>gameplay.cpp(49) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>gameplay.cpp(49) : error C2371: 'weapons' : redefinition; different basic types
1>        gameplay.cpp(48) : see declaration of 'weapons'
1>gameplay.cpp(49) : error C2440: 'initializing' : cannot convert from 'machineGun *' to 'int []'
1>        There are no conversions to array types, although there are conversions to references or pointers to arrays
1>gameplay.cpp(50) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>gameplay.cpp(50) : error C2369: 'weapons' : redefinition; different subscripts
1>        gameplay.cpp(48) : see declaration of 'weapons'
1>gameplay.cpp(50) : error C2440: 'initializing' : cannot convert from 'flamer *' to 'int [1]'
1>        There are no conversions to array types, although there are conversions to references or pointers to arrays




我采取了另一种不同的方法并得到了一些不同的错误。我仍然很不确定这一切是如何粘合在一起的。

//Weapon variables
const int totalWeapons = 2;
int currentWeapon = 1;
weapon weapons[totalWeapons] = {new machineGun, new flamer};

有错误:

1>gameplay.cpp(48) : error C2275: 'machineGun' : illegal use of this type as an expression
1>        gameplay.h(36) : see declaration of 'machineGun'
1>gameplay.cpp(48) : error C2275: 'flamer' : illegal use of this type as an expression
1>        gameplay.h(41) : see declaration of 'flamer'




答案最终是这样的:

//Weapon variables
const int totalWeapons = 2;
int currentWeapon = 1;
weapon *weapons[totalWeapons] = {new machineGun, new flamer};

感谢所有帮助我解决这个问题的人!

【问题讨论】:

  • 如果您只是计划拥有固定数量的武器类型,这很好;然后你会有类似weapons[0] = new machineGun; weapons[1] = new flamer;
  • 你声明了一系列武器,你的机关枪和喷火器都是武器。这不行吗?
  • @isbadawi,你能看一下我的编辑吗,我似乎无法正常工作。

标签: c++ polymorphism


【解决方案1】:
#include <iostream>

class weapon {

 public:
  int fireRate;
  int bulletDamage;
  int range;
  int activeBullet;

 public:
  virtual void fire(void) {std::cout << "machine " << '\n';}
  virtual ~weapon() {std::cout << "destructor is virtual" << '\n';}
};

class machineGun: public weapon {
 public: 
  void fire(void) {std::cout << "machine gun firing" << '\n';}
  ~machineGun(void) { std::cout << "machine gun destroyed" << '\n';}
};

class flamer: public weapon {
 public: 
  void fire(void) {std::cout << "flamer firing" << '\n';}
  ~flamer(void) {std::cout << "flamer destroyed" << '\n';}
};

int main(void)
{
    const int count = 2;
    weapon *weapons[count];

    machineGun *a = new machineGun();
    flamer     *b = new flamer();

    weapons[0] = a;
    weapons[1] = b;

    weapons[0]->fire();
    weapons[1]->fire();

    delete a;
    delete b;

}

【讨论】:

  • 感谢您帮助我了解所有这些内容。
【解决方案2】:

正如罗斯所说,你的阵列必须是武器类型*,才能让你向下转换特殊的武器类型。

所以,

weapon* weapons[totalWeapons];
weapons[0] = new machineGun;

如上所述,当您动态创建它们时,您需要确保稍后清理它们,否则您将遇到内存泄漏

【讨论】:

    【解决方案3】:

    fire() 需要是虚拟的 - 这样,如果你调用它,就会调用正确的实现。

    声明为

    virtual void fire();

    然后,您只需分配适当类型的对象,例如 weapon[0] = new flamer(); - 请务必在完成后删除它,或者在重新分配同一插槽上的另一个对象之前。

    除此之外,您的方法正是应该如何实现多态性。 (当然,您可以考虑使用不同于 C 样式数组的存储,或者确保您实施了正确的边界检查,但这超出了您的问题范围)。

    (旁注:如果有虚函数,还需要添加虚析构函数。)

    【讨论】:

    • 我会研究一下,但是如何让武器数组中的元素 [0] 代表一个类或另一个类?
    • 我修改了答案来解决这个问题。
    • 感谢您的帮助! +1。你能不能看一下我的编辑?
    【解决方案4】:

    不完全准确。我会使用指针,否则你会有切片效果。也就是说,为该数组中的每个区域分配的内存仅足够用于武器。如果机枪或火焰喷射器具有额外的属性,它们将从数组中保存的内容中“丢失”,因为没有足够的内存。如果您使用指针并动态分配数组中的每个武器,则不会出现切片问题。所以你对数组的声明是weapon* weapons[total weapons];,当你声明数组的每个元素时,weapons[numweapon]=new flamer(params);不要忘记析构函数,不要忘记删除动态分配的变量。

    【讨论】:

    • 哎呀,我的答案发布得太晚了。 Ebo 已修改以反映动态分配。
    • 我是第一次学习的菜鸟,我很高兴两种武器的参数相同,但感谢您给我一些思考。
    猜你喜欢
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多