自行制作了一个Redo和Undo功能,可惜不太好,大家帮帮忙
想写一个Undo和Redo的功能,因为参数最多也就是5个,准备自己写。因为有点害怕模板,平时用的也少,一到关键时刻就歇菜了。
现在的代码如下.还有个隐忧,就是实现的那个地方,typedef NmFnCall <T> Call;感觉返回类型等于一开始就确定了,经过测试的确不好。变成了只能返回一种类型的实现,而开始想要的是实现任意类型的返回
//-----------------------------------------------------
//基类
//-----------------------------------------------------
template <class R>
class NmFnCall
{
public:
virtual R Run() = 0;
};
//-----------------------------------------------------
//无参的函数指针
//-----------------------------------------------------
template <class R>
class NormalFnNon:public NmFnCall <R>
{
public:
explicit NormalFnNon( R (*p)() ):fp(p){}
R Run() {return (*fp)();}
private:
R (*fp)();
};
template <class R>
NormalFnNon <R> * CreateNFNon( R (*p)() )
{
return new NormalFnNon <R> (p);
}
//-----------------------------------------------------
//实现
//-----------------------------------------------------
template <class T>
class RUdo
{
public:
typedef NmFnCall <T> Call;
bool Empty() const{return _fn_call.empty();}
bool Pop()
{
if( _fn_call.empty()==true ) return false;
_fn_call.top()-> Run();
_fn_call.pop();
return true;
}
template <class R>
void Push( R(*f)() )
{
_fn_call.push( CreateNFNon(f) );
}
private:
std::stack <Call*> _fn_call; //函数调用
};
#endif
[解决办法]
根据你所用对象的类型而放入适当的函数返回类型。的确应该这样啊。
像上面注释掉的两句肯定不会对。
void main(void)
{
RUdo <int> r1;
RUdo <const char*> r2;
RUdo <void> r3;
r3.Push <void> (&Hello);
r1.Push <int> (&Sum);
r2.Push <const char*> (&Display);
}
所谓范型不是说同种对象可以有多个类型,而是说可以通过模板定义各种不同模板参数的对象。
如果你想用RUdo来保存各种不同的函数返回类型,一个比较简单的方法是使RUdo成为“抽象类”——其实并不需要真正的抽象,而是将其成员全都成为static。
template <typename T>
class RUdo
{
public:
static bool Empty()
{
return _fn_call.empty();
}
static bool Pop()
{
if( _fn_call.empty()==true )
return false;
_fn_call.top()-> Run();
_fn_call.pop();
return true;
}
//template <class R> < Amazing approach but ineffective >
static void Push( /* R */ T(*f)() )
{
_fn_call.push( CreateNFNon(f) );
}
private:
typedef NmFnCall <T> Call;// Place it in the private region 'cause it does not need to be externally accessed.
static std::stack <Call*> _fn_call; //函数调用
private:
RUdo(void)// Disable this class to create an object(instance).
{
}
};
template <typename T>
std::stack < RUdo <T> ::Call * > RUdo <T> ::_fn_call;// Initialize static member
void Hello(void)
{
cout < < "Hello, world! " < < endl;
}
int Sum(void)
{
return 1;
}
const char* Display(void)
{
const char *s = "OK! ";
cout < < s < < endl;
return s;
}
void main(void)
{
RUdo <int> ::Push(&Sum);
RUdo <const char*> ::Push(&Display);
RUdo <void> ::Push(&Hello);
RUdo <void> ::Pop();
RUdo <const char*> ::Pop();
RUdo <int> ::Pop();
}
注意,在Visual .NET2003中,对
template <typename T>
std::stack < RUdo <T> ::Call * > RUdo <T> ::_fn_call;// Initialize static member
支持的不好。在VisualDSP++中可以通过编译,这可能是微软C/C++编译器的一个BUG。
只能用:
template <typename T>
std::stack < RUdo <T> ::Call * > RUdo <T> ::_fn_call;
不知这样做你是否满意?
[解决办法]
楼主,你的返回值不是都忽略了没使用嘛,那你讨论返回值如何如何干嘛?
[解决办法]
为什么不看看设计模式中的命令模式?