Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 父类型的继承容器不能容纳子级?_C++_Inheritance_Vector_Casting - Fatal编程技术网

C++ 父类型的继承容器不能容纳子级?

C++ 父类型的继承容器不能容纳子级?,c++,inheritance,vector,casting,C++,Inheritance,Vector,Casting,我有一个父菜单类和子菜单主菜单、设置菜单、暂停菜单等 我想把它们都放在一个向量里 我能行 std::vector<Menu*> myVector; 它可以编译,但有些东西不起作用了 它不一定是一个向量,但我希望能够遍历它们 我一直在尝试实现Observer模式,在继承方面我也遇到了困难 对于观察者模式,我有一个观察者类,游戏继承了观察者。我有一个由InputComponent继承的主题类。Subject有一个名为vObserver的Observer*向量和一个名为addObser

我有一个父菜单类和子菜单主菜单、设置菜单、暂停菜单等

我想把它们都放在一个向量里

我能行

std::vector<Menu*> myVector;
它可以编译,但有些东西不起作用了

它不一定是一个向量,但我希望能够遍历它们

我一直在尝试实现Observer模式,在继承方面我也遇到了困难


对于观察者模式,我有一个观察者类,游戏继承了观察者。我有一个由InputComponent继承的主题类。Subject有一个名为vObserver的Observer*向量和一个名为addObserver(Observer*Observer)的函数,并在vObserver中添加传递的指针。我还有一个名为Notify(event e)的函数,它迭代vObserver并调用它们的onNotify函数

所以在游戏中,我有一个名为inputComp的InputComponent实例。我执行inputComp.addObserver(this),inputComp.vObserver.size()为1。好。我在InputComponent中调用了Notify,但当它执行时,主题中的vObserver.size为0。。。我知道我做错了什么

编辑:

class Menu
{
public:
    virtual void draw() = 0;
    virtual void onMouseMove(int x, int y) = 0;
    virtual void onMouseButton(int button, bool is_down) = 0;
    friend class InputComponent;
    friend class MainMenuInputComponent;
protected:
    SDL_Renderer* _renderer;
    std::vector<Button> vButton;
    std::vector<SDL_Texture *> vTexture;
};

class MainMenu :  public Menu
{
public:
    MainMenu(SDL_Renderer* renderer);
    virtual void draw();
    virtual void onMouseMove(int x, int y);
    virtual void onMouseButton(int button, bool is_down);
    friend class MainMenuInputComponent;
};



class InputComponent: public Subject
{
public:
    virtual void processInput()
    {}
    static bool isMouseWithin(int mouseX, int mouseY, SDL_Rect rect)
    {
        if (mouseX >= rect.x && mouseX <= rect.x + rect.w && mouseY >= rect.y && mouseY <= rect.y + rect.h)
            return true;
        else
            return false;
    }
};

class MainMenuInputComponent : public InputComponent
{
public:
    MainMenuInputComponent(MainMenu* owner)
        :_owner(owner){}
    virtual void processInput();
    virtual void onBtnClick(std::string btnName);

    MainMenu* _owner;
};

class Game : public Observer
{
public:

Game();
void initSDL();
void initGame();
void processGameInput();
void renderGame();
void update();
virtual void onNotify(Events e);

SDL_Window* myWindow;
SDL_Renderer* myRenderer;
std::vector<MainMenuInputComponent> vInputComponent;
std::stack<MainMenu*> menuStack;
};


Game::Game()
{
    initSDL();
    initGame();
}

void Game::initGame()
{
    //Create the Main Menu
    MainMenu* pMainMenu = new MainMenu(myRenderer);
    //Add menu to the stack
    menuStack.push((pMainMenu));
        //Add it's components to respective arrays
    MainMenuInputComponent inputComp = MainMenuInputComponent(pMainMenu);
    vInputComponent.push_back(inputComp);
        //Add Observer/Subject relationship.
    inputComp.addObserver((Observer*)this);
    int bob = (int)inputComp.vObserver.size(); //to see if size went up


}

void Game::processGameInput()
{
    if (!menuStack.empty())
    {
        for (int i = 0; i < (int)vInputComponent.size(); i++)
        {
            //Menu* compOwner = (Menu*)(vInputComponent[i]._owner);
            //std::unique_ptr<Menu, std::default_delete<Menu>> a = menuStack.top();
            if ((vInputComponent[i]._owner) == menuStack.top())
            {
                vInputComponent[i].processInput();
            }
            //vInputComponent[i].processInput();
        }
    }
    else
    for (int i = 0; i < (int)vInputComponent.size(); i++)
    {
        vInputComponent[i].processInput();
    }
}

void Game::renderGame()
{
    SDL_RenderClear(myRenderer);
    MainMenu* bob = menuStack.top();
    if (!menuStack.empty())
        (menuStack.top())->draw();
    SDL_RenderPresent(myRenderer);
}

void Game::onNotify(Events event)
{
    switch (event)
    {
    case POP_MENU:
        menuStack.pop();
        break;
    case GOTO_SETTINGS:
        //Menu* pSettingsMenu =(Menu*)(new SettingsMenu(myRenderer));
        //menuStack.push(std::unique_ptr<Menu>(pSettingsMenu));
        break;
        // Handle other events, and update heroIsOnBridge_...
    }
}

class Subject
{
public:
    void addObserver(Observer* observer)
    {
        vObserver.push_back(observer);
    }

    void removeObserver(Observer* observer)
    {
        //vObserver.erase(std::find(vObserver.begin(), vObserver.end(), 8));
    }


    std::vector<Observer*> vObserver;
protected:
    void notify(Events e)
    {
        for (int i = 0; i < (int)vObserver.size(); i++)
        {
            vObserver[i]->onNotify(e);
        }
    }
};

class Observer
{
public:
    virtual ~Observer() {}

    virtual void onNotify(Events e) = 0;
};
类菜单
{
公众:
虚空绘制()=0;
MouseMove上的虚空(intx,inty)=0;
虚拟void onMouseButton(int按钮,bool向下)=0;
友元类输入组件;
友元类MainMenuInputComponent;
受保护的:
SDL_渲染器*_渲染器;
std::矢量按钮;
std::向量vTexture;
};
类主菜单:公共菜单
{
公众:
主菜单(SDL_渲染器*渲染器);
虚空绘制();
mousemove上的虚拟void(intx,inty);
虚拟void onMouseButton(int按钮,bool向下);
友元类MainMenuInputComponent;
};
类InputComponent:公共主题
{
公众:
虚拟void processInput()
{}
静态bool ismouseinin(int mouseX、int mouseY、SDL_Rect)
{

如果(mouseX>=rect.x&&mouseX=rect.y&&mouseY

class Menu {};
class MainMenu : public Menu {};

std::vector<Menu*> myVector;
MainMenu* pMainMenu = // ...
myVector.push_back(pMainMenu);
预期产出:

Hello world! from MainMenu Hello world! from PauseMenu Hello world! from SettingsMenu 你好,世界!从主菜单 你好,世界!来自PauseMenu 你好,世界!来自设置菜单
这应该也能起作用,并给你额外的功能,为你管理内存。

你是这样的受害者吗?是的……当我做了std::vector时,它工作了,但这很愚蠢,因为我不会有多个主菜单…!怎么办?@user1420563请不要试图用其他评论来改进你的帖子。只是p在水平条上画一条线,并将此信息添加到您的问题中。@user1420563:很抱歉,您需要创建问题的答案。很好,您提供了代码片段,但按照编写方式,它们甚至不会编译,因此我无法观察您看到的行为。如果您希望其他人提供帮助,您需要将您的问题缩小到f最多只有几百行。好吧,我正在努力,尽量不放太多的代码,但它们都是相关的。我使用的是unique_ptr,事实上不同的菜单都在一个堆栈中,但由于某种原因,当我执行myStack.top()->functionCall()时,它给了我一个wierd内存错误。我试图确定myStack.top()到底是什么,所以我创建了一个变量并将其分配给该变量,这样我就可以在调试器中查看它的值,但是它说了一些我试图访问删除的函数或其他东西的内容。所以我只使用普通指针,它就去掉了that@user1420563:如果您的
菜单
s在堆栈上,那么为什么您有
pMainMenu=new main menu;
在您的问题中?您可以更新您的问题以反映您实际拥有的内容吗?默认情况下,
shared_ptr
unique_ptr
将处理您的指针,就像它们指向动态存储,而不是堆栈对象,这可能解释您看到错误的原因。好的,我希望我的代码足够了如果你想要更多,请告诉我
#include <vector>
#include <memory>
#include <iostream>

class Menu
{
public:
    virtual void on_event() = 0;
    // virtual destructor needed for polymorphic base classes
    virtual ~Menu() {}
};

class MainMenu : public Menu
{
public:
    virtual void on_event()
    {
        std::cout << "Hello world! from MainMenu" << std::endl;
    }
};

class PauseMenu : public Menu
{
public:
    virtual void on_event()
    {
        std::cout << "Hello world! from PauseMenu" << std::endl;
    }
};

class SettingsMenu : public Menu
{
public:
    virtual void on_event()
    {
        std::cout << "Hello world! from SettingsMenu" << std::endl;
    }
};

int main()
{
    std::vector<std::shared_ptr<Menu>> myVector;
    myVector.push_back(std::make_shared<MainMenu>());
    myVector.push_back(std::make_shared<PauseMenu>());
    myVector.push_back(std::make_shared<SettingsMenu>());
    for(auto& menu : myVector) {
        menu->on_event();
    }
    return 0;
}
Hello world! from MainMenu Hello world! from PauseMenu Hello world! from SettingsMenu