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