今天在看《程序员面试宝典》第二版P102例1的时候,由于对题目答案不满意,自己设计了一个command模式的实现方式,但是在实现过程中遇到了一些问题,分享如下:
#include<iostream>
#include<vector>
#include<tr1/memory>
#include "../clearPcont.h"//自己编写的析构指针向量的模板函数头文件
using namespace std;
using std::tr1::shared_ptr;//为解决Receiver析构三次引入的智能指针
class Receiver
{
public:
~Receiver()
{
cout<<"recv destruct called!/n";
}
template<typename T>//普通类中实现模板函数
const T AddAction(const T& x,const T& y)
{
cout<<"AddAction called!/n";
return x+y;
}
template<typename T>
const T MultAction(const T& x,const T& y)
{
cout<<"MultAction called!/n";
return x*y;
}
template<typename T>
const T JudgAction(const T& x,const T& y)
{
cout<<"JudgAction called!/n";
if(x>=0)
return x;
else
{
if(0==y)
return -1;
return x/y;
}
}
};
template<typename T>
class Command//按照针对接口编程的原则,这里没有将Receive指针放到command基类中,这也为下面的三次析构埋下了炸弹
{
public:
virtual ~Command(){}
virtual const T Exec(const T&,const T&)=0;//注意在这个地方,虚函数不能设计成模板函数,因为编译器无法构建虚函数表,
//解决方法就是将类声明为模板类,这样就可以。
};
template<typename T>
class Invoker
{
private:
Command<T>* m_command;
public:
Invoker(Command<T>* pCom):m_command(pCom)
{
cout<<"Invoker constructor called!/n";
}
~Invoker()
{
cout<<"Invoker destruct called!/n";
if(m_command)
delete m_command;
m_command=0;
}
const T operator()(const T& x,const T& y)
{
return m_command->Exec(x,y);
}
};
template<typename T>
class AddCommand:public Command<T>
{
private:
Receiver* m_recv;
public:
AddCommand(Receiver* recv):m_recv(recv){}
virtual ~AddCommand()//刚开始没有注释下面的句子,结果导致3此析构Receive指针
{
cout<<"Addcmd destruct called!/n";
/*
if(m_recv)
{
cout<<"del recv from add!/n";
delete m_recv;
}
*/
m_recv=0;
}
virtual const T Exec(const T& x,const T& y)
{
return m_recv->AddAction(x,y);
}
};
template<typename T>
class MultCommand:public Command<T>
{
private:
Receiver* m_recv;
public:
MultCommand(Receiver* recv):m_recv(recv){}
virtual ~MultCommand()
{
cout<<"Multcmd destruct called!/n";
/*
if(m_recv)
{
cout<<"del recv from mult!/n";
delete m_recv;
}
*/
m_recv=0;
}
virtual const T Exec(const T& x,const T& y)
{
return m_recv->MultAction(x,y);
}
};
template<typename T>
class JudgCommand:public Command<T>
{
private:
Receiver* m_recv;
public:
JudgCommand(Receiver* recv):m_recv(recv){}
virtual ~JudgCommand()
{
cout<<"Judgcmd destruct called!/n";
/*
if(m_recv)
{
cout<<"del recv from Judg!/n";
delete m_recv;
}
*/
m_recv=0;
}
virtual const T Exec(const T& x,const T& y)
{
return m_recv->JudgAction(x,y);
}
};
int main()
{
int a=100,b=-10;
//Receiver* pRecv=new Receiver;
shared_ptr<Receiver> pRecv=shared_ptr<Receiver>(new Receiver)//);//注释掉显式析构pRecv的内容后用智能指针来管理即可
vector<Command<int>*> vecPCmd;
vecPCmd.push_back(new AddCommand<int>(pRecv.get()));
vecPCmd.push_back(new MultCommand<int>(pRecv.get()));
vecPCmd.push_back(new JudgCommand<int>(pRecv.get()));
vector<Invoker<int>*> vecPInvk;
vecPInvk.push_back(new Invoker<int>(vecPCmd[0]));
vecPInvk.push_back(new Invoker<int>(vecPCmd[1]));
vecPInvk.push_back(new Invoker<int>(vecPCmd[2]));
for(vector<Invoker<int>*>::iterator iter=vecPInvk.begin();iter!=vecPInvk.end();++iter)
{
(*iter)->operator()(a,b);
}
clearPCont(vecPInvk);//显式析构new的对象,但是pRecv没有被析构,因为代码被注释掉了
return 0;//main函数执行结束,智能指针自动析构pRecv
}