首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

自行制作了一个Redo和Undo功能,可惜不太好,大家帮帮忙,该怎么处理

2012-03-24 
自行制作了一个Redo和Undo功能,可惜不太好,大家帮帮忙想写一个Undo和Redo的功能,因为参数最多也就是5个,准

自行制作了一个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;

不知这样做你是否满意?

[解决办法]
楼主,你的返回值不是都忽略了没使用嘛,那你讨论返回值如何如何干嘛?
[解决办法]
为什么不看看设计模式中的命令模式?

热点排行