C ++将派生结构传递给期望超级结构的方法

时间:2016-06-28 05:51:07

标签: c++ struct

我正在尝试使用C ++和OOP为arduino创建一个菜单库。

我有一个名为:

的结构
struct MenuItem {
    int position;
    String name;

    MenuItem(int position, String name) : position(position), name(name) { };
};

我有一个名为:

的派生结构
struct SpecificMenuItem : MenuItem {
    int count;

    SpecificMenuItem(int position, String name, int count) : MenuItem(position, name) , count(count) { };
};

如何将SpecificMenuItem结构数组传递给期望数组MenuItem的方法?这里的想法是来自MenuItem的所有派生结构应该具有positionname,以便可以使用Menu类中的以下方法呈现简单列表:

Menu::Menu() {
}

void Menu::setMenuItems(MenuItem *menuItems) {
  this->mMenuItems = menuItems;
}
void Menu::render(void) {
    for (int j = 0; j < this->mMenuItemSize; j++) {
        Serial.println(this->mMenuItems[j].name);
    }
}

specific_menu.h的头文件:

class SpecificMenu : public Menu {
    struct SpecificMenuItem mSpecificMenuItem[2] = {
      {1, "Name", 3},
      {2, "Name 2", 4}
    };
  public:
    SpecificMenu();
};

specific_menu.cpp的cpp文件:

SpecificMenu::SpecificMenu() : Menu() {
  this->setMenuItems(this->mSpecificMenuItem);
  this->setMenuItemsSize(2);
}

现在的问题是在count结构中拥有额外的SpecificMenuItem成员会导致程序崩溃,但是如果删除count成员,程序运行正常,但是我认为这只是一个侥幸,它的工作原理。很想知道如何让上述工作起作用。

干杯!

3 个答案:

答案 0 :(得分:1)

即使SpecificMenuItem继承自MenuItem,您也无法将SpecificMenuItem数组传递给等待MenuItem数组的方法。

一种可能的方法是删除setMenuItems方法并利用多态来访问菜单的大小和项目:

class Menu {
protected:
    virtual size_t size () const = 0;
    virtual MenuItem& operator[] (size_t) = 0;
};

class SpecificMenu : public Menu {
    SpecificMenuItem mSpecificMenuItem[2] = {
        {1, "Name", 3},
        {2, "Name 2", 4}
    };
protected:
    virtual size_t size () const { return 2; }
    virtual const MenuItem& at (size_t i) const {
        return mSpecificMenuItem[i];
    }
public:
    SpecificMenu();
};

然后在Menu::render中使用这些方法:

void Menu::render(void) {
    for (int j = 0; j < this->size(); j++) {
        Serial.println(this->at(j).name);
    }
}

这会使您的Menu充当&#34; MenuItem&&#34;的一个(抽象)容器。

答案 1 :(得分:0)

您最好宣布以下内容:

typedef std::list<MenuItem *> MenuItemArray;

然后你可以通过指针访问基类。

void 
Menu::setMenuItems(const MenuItemArray& menuItems) 
{
  this->mMenuItems = menuItems;
}

void 
Menu::render(void) 
{
    for (int j = 0; j < this->mMenuItems.size(); j++) {
        Serial.println(this->mMenuItems[j]->name);
    }
}

之后,如果您需要访问SpecificMenuItem元素:

...
SpecificMenuItem *specificItem = dynamic_cast<SpecificMenuItem *>(mMenuItems[i]);
if (specificItem) {
   ...
}

你最初写的解决方案看起来像C解决方案,而不是C ++恕我直言。

玩得开心。

答案 2 :(得分:0)

您的问题是,您不能将不同的结构/类放在同一个数组中,因为它们具有不同的大小。考虑制作指针数组,指向基类的对象,因为它们也可以指向派生类。像

typedef MenuItem * MenuItemPtr;
typedef MenuItemPtr * MenuItemPtrArray;
MenuItemPtrArray myArr= new MenuItemPtr[2];
myArr[1] = new MenuItem(/*...*/);
myArr[2] = new SpecificMenuItem(/*....*/);

当然,你可以在他的回答中使用std::list或@Holt建议的其他收藏品,这将是更好的解决方案。但是我想你没有为arduino写的,没有stl