实现command模式中涉及到的虚函数、模板和其他

今天在看《程序员面试宝典》第二版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
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值