C++;派生类问题 我正在用C++做游戏,我的派生类有问题。我有一个名为GameScreen的基类,它有一个vitrual void draw()函数,没有任何语句。我还有一个名为MenuScreen的派生类,它也有一个虚拟的void draw()函数,还有一个名为TestMenu的MenuScreen派生类,它也有一个void draw()函数。在我的程序中,我有一个游戏屏幕列表,我有一个游戏屏幕迭代器通过调用每个游戏屏幕draw()函数
问题是我在游戏屏幕列表中放置了一个TestMenu对象。它不是调用TestMenu的draw()函数的迭代器,而是调用GameScreen类的draw()函数。有人知道我如何调用TestMenu的draw()函数而不是GameScreen中的函数吗 以下是函数:C++;派生类问题 我正在用C++做游戏,我的派生类有问题。我有一个名为GameScreen的基类,它有一个vitrual void draw()函数,没有任何语句。我还有一个名为MenuScreen的派生类,它也有一个虚拟的void draw()函数,还有一个名为TestMenu的MenuScreen派生类,它也有一个void draw()函数。在我的程序中,我有一个游戏屏幕列表,我有一个游戏屏幕迭代器通过调用每个游戏屏幕draw()函数,c++,inheritance,C++,Inheritance,问题是我在游戏屏幕列表中放置了一个TestMenu对象。它不是调用TestMenu的draw()函数的迭代器,而是调用GameScreen类的draw()函数。有人知道我如何调用TestMenu的draw()函数而不是GameScreen中的函数吗 以下是函数: // Tell each screen to draw itself. //gsElement is a GameScreen iterator //gsScreens is a list of type GameScreen
// Tell each screen to draw itself.
//gsElement is a GameScreen iterator
//gsScreens is a list of type GameScreen
void Draw()
{
for (gsElement = gsScreens.begin(); gsElement != gsScreens.end(); gsElement++)
{
/*if (gsElement->ssState == Hidden)
continue;*/
gsElement->Draw();
}
}
以下是我的课程:
class GameScreen {
public:
string strName;
bool bIsPopup;
bool bOtherScreenHasFocus;
ScreenState ssState;
//ScreenManager smScreenManager;
GameScreen(string strName){
this->strName = strName;
}
//Determine if the screen should be drawn or not
bool IsActive(){
return !bOtherScreenHasFocus &&
(ssState == Active);
}
//------------------------------------
//Load graphics content for the screen
//------------------------------------
virtual void LoadContent(){
}
//------------------------------------
//Unload content for the screen
//------------------------------------
virtual void UnloadContent(){
}
//-------------------------------------------------------------------------
//Update changes whether the screen should be updated or not and sets
//whether the screen should be drawn or not.
//
//Input:
// bOtherScreenHasFocus - is used set whether the screen should update
// bCoveredByOtherScreen - is used to set whether the screen is drawn or not
//-------------------------------------------------------------------------
virtual void Update(bool bOtherScreenHasFocus, bool bCoveredByOtherScreen){
this->bOtherScreenHasFocus = bOtherScreenHasFocus;
//if the screen is covered by another than change the screen state to hidden
//else set the screen state to active
if(bCoveredByOtherScreen){
ssState = Hidden;
}
else{
ssState = Active;
}
}
//-----------------------------------------------------------
//Takes input from the mouse and calls appropriate actions
//-----------------------------------------------------------
virtual void HandleInput(){
}
//----------------------
//Draw content on screen
//----------------------
virtual void Draw(){
}
//--------------------------------------
//Deletes screen from the screen manager
//--------------------------------------
void ExitScreen(){
//smScreenManager.RemoveScreen(*this);
}
};
class MenuScreen: public GameScreen{
public:
vector <BUTTON> vbtnMenuEntries;
MenuScreen(string strName):GameScreen(strName){
}
virtual void Update(bool bOtherScreenHasFocus, bool bCoveredByOtherScreen){
GameScreen::Update(bOtherScreenHasFocus, bCoveredByOtherScreen);
for(unsigned int i = 0; i < vbtnMenuEntries.size(); i++){
vbtnMenuEntries[i].IsPressed();
}
}
virtual void Draw(){
GameScreen::Draw();
for(unsigned int i = 0; i < vbtnMenuEntries.size(); i++)
vbtnMenuEntries[i].Draw();
}
};
class testMenu : public MenuScreen{
public:
vector<OBJECT> test;
//OBJECT background3();
// OBJECT testPic(512, 384, buttonHover.png, 100, 40, 100, 40);
// BUTTON x(256, 384, buttonNormal.png, buttonHover.png, buttonPressed.png, 100, 40, test());
bool draw;
testMenu():MenuScreen("testMenu"){
OBJECT background3(1, 1, 0, TEXT("background.png"), 1, 1, 1024, 768);
OBJECT testPic(512, 384,0, TEXT("buttonHover.png"), 1, 1, 100, 40);
test.push_back(background3);
test.push_back(testPic);
//background3.Init(int xLoc, int yLoc, int zLoc, LPCTSTR filePath, int Rows, int Cols, int Width, int Height)
//test.push_back(background3);
// vbtnMenuEntries.push_back(x);
draw = false;
}
void Update(bool bOtherScreenHasFocus, bool bCoveredByOtherScreen){
MenuScreen::Update(bOtherScreenHasFocus, bCoveredByOtherScreen);
//cout << "X" << endl;
/*if(MouseLButton == true){
testMenu2 t;
smManager.AddScreen(t);
}*/
}
void Draw(){
//background3.Draw();
test[0].Draw();
test[1].Draw();
MenuScreen::Draw();
///*if(draw){*/
// testPic.Draw();
//}
}
/*void test(){
draw = true;
}*/
};
类游戏屏幕{
公众:
字符串strName;
布尔-比斯波;
布尔;哈斯福克斯;
屏幕状态ssState;
//屏幕管理器smScreenManager;
游戏屏幕(字符串strName){
这个->strName=strName;
}
//确定是否应绘制屏幕
bool IsActive(){
return!hasFocus&&
(ssState==活动);
}
//------------------------------------
//加载屏幕的图形内容
//------------------------------------
虚拟void LoadContent(){
}
//------------------------------------
//卸载屏幕的内容
//------------------------------------
虚拟内容{
}
//-------------------------------------------------------------------------
//更新更改是否应更新屏幕并设置
//是否绘制屏幕。
//
//输入:
//设置屏幕是否应该更新
//bCoveredByOtherScreen-用于设置是否绘制屏幕
//-------------------------------------------------------------------------
虚拟无效更新(bool屏幕聚焦,bool bCoveredByOtherScreen){
此->困扰屏幕聚焦=困扰屏幕聚焦;
//如果屏幕被另一个屏幕覆盖,则将屏幕状态更改为隐藏
//否则,将屏幕状态设置为“活动”
如果(b位于另一屏幕上){
ssState=隐藏;
}
否则{
ssState=活动状态;
}
}
//-----------------------------------------------------------
//从鼠标获取输入并调用适当的操作
//-----------------------------------------------------------
虚拟void HandleInput(){
}
//----------------------
//在屏幕上绘制内容
//----------------------
虚空绘制(){
}
//--------------------------------------
//从屏幕管理器中删除屏幕
//--------------------------------------
void ExitScreen(){
//smScreenManager.RemoveScreen(*此项);
}
};
类菜单屏幕:公共游戏屏幕{
公众:
向量向量向量;
菜单屏幕(字符串strName):游戏屏幕(strName){
}
虚拟无效更新(bool屏幕聚焦,bool bCoveredByOtherScreen){
游戏屏幕::更新(屏幕聚焦,bCoveredByOtherScreen);
for(无符号整数i=0;i //cout如果gsScreens是一个对象列表而不是指针列表(如代码所示),那么您并没有存储您认为存储在其中的内容
所发生的事情是——您实际上不是将TestMenu放入列表,而是使用编译器生成的复制构造函数构造一个新的MenuScreen,并将此MenuScreen放入列表
C++通过指针是多态的,因此如果没有指针,就不会有多态行为。如果gsScreens是一个对象列表而不是指针列表(如代码所示),那么就没有存储您认为存储在其中的内容
所发生的事情是——您实际上不是将TestMenu放入列表,而是使用编译器生成的复制构造函数构造一个新的MenuScreen,并将此MenuScreen放入列表
C++通过指针是多态的,因此如果没有指针,就不会有多态行为。要获得所追求的多态行为,同时使用std::vector
,必须在向量中存储指向基类类型的指针,而不是存储值。此外,必须记住在如果向量超出范围
例如:
#include <vector>
#include <algorithm>
struct Base
{
virtual void Foo() = 0;
virtual ~Base() { }
};
struct Derived1 : public Base
{
void Foo() { }
};
struct Derived2 : public Base
{
void Foo() { }
};
struct delete_ptr
{
template <typename T>
void operator()(T& p)
{
delete p;
p = 0;
}
};
int wmain(int, wchar_t*[])
{
std::vector<Base*> items;
items.push_back(new Derived1);
items.push_back(new Derived2);
Base& first = items.front();
first.Foo(); // Will boil down to Derived1::Foo().
Base& last = items.back();
last.Foo(); // Will boil down to Derived2::Foo().
std::for_each(items.begin(), items.end(), delete_ptr())
};
#包括
#包括
结构基
{
虚拟void Foo()=0;
虚拟~Base(){}
};
结构派生1:公共基
{
void Foo(){}
};
结构派生2:公共基础
{
void Foo()
#define DISALLOW_COPYING(X) \
private: \
X(const X &); \
const X& operator= (const X& x)
class Foo {
// ...
DISALLOW_COPYING(Foo);
};