我有一些有点棘手的解释,所以我会尽我所能。我有一个显示箭头&的指令屏幕类。解释每个按钮的功能的文本块&所以在InstructionScreen中我有一堆成员函数,每个函数都会创建一些箭头&用于解释不同按钮的内容的文本。
指令屏幕将被子类化为MenuInstructScreen,OptionsInstructScreen&等等,在这些课程中,我将创建自定义函数,创建箭头&文字解释他们的屏幕按钮。
问题是在InstructionScreen中声明这个堆栈,因为它将包含属于其子类的函数。我想我可以做到这一点,但我使用模板吗?
简而言之,问题是如何声明一个包含不存在的类的成员函数的堆栈?
问题更易于理解和解决。看看你看这个简单的例子:
typedef class InstructionScreen;
typedef class MenuInstructScreen;
template <typename FooClass>
typedef void (FooClass::*MemberFuncPtr)(); // will be typedef void (MenuInstructScreen::*MemberFuncPtr)();
class InstructionScreen
{
public:
InstructionScreen() {}
void runInstructions()
{
while ( !instructionStep.empty() )
{
(this->*instructionStep.top())();
instructionStep.pop();
}
}
protected:
stack <MemberFuncPtr> instructionStep;
};
class MenuInstructScreen : public InstructionScreen
{
public:
MenuInstructScreen()
{
// Set instruction schedule
instructionStep.push( &MenuInstructScreen::step2() );
instructionStep.push( &MenuInstructScreen::step1() );
}
void step1()
{
// create some widgets that point to buttons & widgets that contain text instructions
}
void step2()
{
// create some widgets that point to buttons & widgets that contain text instructions
}
private:
};
class OptionsInstructScreen : public InstructionScreen
{
public:
OptionsInstructScreen()
{
// Set instruction schedule
instructionStep.push( &OptionsInstructScreen::step2() );
instructionStep.push( &OptionsInstructScreen::step1() );
}
void step1()
{
// create some widgets that point to buttons & widgets that contain text instructions
}
void step2()
{
// create some widgets that point to buttons & widgets that contain text instructions
}
private:
};
答案 0 :(得分:1)
C ++不允许模板化的typedef,但C ++ 11通过Template Aliases支持此功能。如果编译器中没有C ++ 11支持,则可以使用Boost.Function
之类的仿函数来实现相同的功能。
typedef boost::function<void()> Func;
由于你的typedef用于不带参数的成员函数,你可以使用aboce定义一个返回void并且不接受任何参数的函子。虽然它不会限于特定类的成员。您可以使用以下内容将项目推送到派生类中的堆栈上:
stack.push(boost::bind(&MenuInstructScreen::step2, this));
stack.push(boost::bind(&MenuInstructScreen::step1, this));
您的原始示例现在看起来像这样......
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <stack>
class InstructionScreen
{
public:
void runInstructions()
{
while (!instructionStep.empty())
{
boost::function<void()> func = instructionStep.top();
instructionStep.pop();
func();
}
}
protected:
std::stack<boost::function<void()> > instructionStep;
};
class MenuInstructScreen : public InstructionScreen
{
public:
MenuInstructScreen()
{
instructionStep.push(boost::bind(&MenuInstructScreen::step2, this));
instructionStep.push(boost::bind(&MenuInstructScreen::step1, this));
}
void step1()
{
//
}
void step2()
{
//
}
};
class OptionsInstructScreen : public InstructionScreen
{
public:
OptionsInstructScreen()
{
instructionStep.push(boost::bind(&OptionsInstructScreen::step2, this));
instructionStep.push(boost::bind(&OptionsInstructScreen::step1, this));
}
void step1()
{
//
}
void step2()
{
//
}
private:
};
int main() { }
答案 1 :(得分:0)
C ++中没有“template typedef”。在C ++ 0x中,您可以使用模板别名,但目前对此的支持有限。
为什么不简单地向基类添加虚函数:
virtual void steps() { };
然后让每个派生类实现它:
void steps() { step1(); step2(); }
然后,您可以在堆栈中存储指向基类的指针,然后只需调用->steps()
。