template多态用法小议

来源:互联网 发布:win10下安装linux 编辑:程序博客网 时间:2024/06/05 14:30

template多态用法小议

template 是编译器绑定。 阅读template就是展开template的后的我们熟知的C++. 例如

template <class T>
class A
{
   T a;
}

直到调用时, 编译器才生产确切的类型。 A<int> a;
class A
{
   int a;
}

template多态是alt的发明。区别去有确定类型关系的继承多态, 他是一种特征多态,即只要符合模板的行为即可, 没有类型约束。

///////////////////////////////////////////////////////////
//Ipc.h

template <class CSS_Communicate>
class CSS_Ipc : public CSS_Non_Copyable
{
public:
 CSS_Ipc();

 ~CSS_Ipc();

public:
 bool init(const char* name);

 void release();

        bool send(void *p, size_t size);

 bool recv(void *p, size_t size);
};

#include "Ipc.inl"

///////////////////////////////////////////////////////////////
//Ipc.inl

template <class CSS_Communicate> inline
CSS_Ipc<CSS_Communicate>::CSS_Ipc()
{
}

template <class CSS_Communicate> inline
CSS_Ipc<CSS_Communicate>::~CSS_Ipc()
{
}

template <class CSS_Communicate> inline
bool CSS_Ipc<CSS_Communicate>::init(const char* name)
{
 CSS_Communicate *t = static_cast<CSS_Communicate *>(this);
 return t->init(name);
}

template <class CSS_Communicate> inline
bool CSS_Ipc<CSS_Communicate>::send(void *p, size_t size)
{
 CSS_Communicate *t = static_cast<CSS_Communicate *>(this);
 return t->send(p, size);
}

template <class CSS_Communicate> inline
bool CSS_Ipc<CSS_Communicate>::recv(void *p, size_t size)
{
 CSS_Communicate *t = static_cast<CSS_Communicate *>(this);
 return t->recv(p, size);
}

template <class CSS_Communicate> inline
void CSS_Ipc<CSS_Communicate>::release()
{
 CSS_Communicate *t = static_cast<CSS_Communicate *>(this);
 t->release();
}

//////////////////////////////////////////////

/////////////////////////////////////////////////
class CSS_IPC_Export CSS_Mem_Map : public CSS_Ipc<CSS_Mem_Map >
{
public:
 CSS_Mem_Map();

 ~CSS_Mem_Map();

public:
 bool init(const char* name);

 void release();

        bool send(void *p, size_t size);

 bool recv(void *p, size_t size);

private:
 HANDLE  map_;
 bool    owner_;
 char    *buf_;
 size_t  size_;
 char    name_[32];

 CSS_Event event_;
 CSS_Guard<CSS_Event> guard_;
};

///////////////////////////////////////////////////
//////////////////////////////////////////

CSS_Mem_Map::CSS_Mem_Map()
  :map_(0),
  owner_(false),
  buf_(0),
  size_(0x100000),
  event_("map event"),
  guard_(event_, false)
{
}

CSS_Mem_Map::~CSS_Mem_Map()
{
}

bool CSS_Mem_Map::init(const char* name)
{
 strcpy(this->name_, name);
 map_=(HANDLE)CreateFileMapping((HANDLE)0xFFFFFFFFFFFF,
                             NULL,
           PAGE_READWRITE,
           0,
           this->size_,
           this->name_);

 if (map_)
 {
  buf_=(char *)MapViewOfFile(map_,
                          FILE_MAP_ALL_ACCESS,
           0,0,0);

  this->owner_ = true;
 }

 return this->owner_;
}

void CSS_Mem_Map::release()
{
 if (this->owner_)
 {
  this->owner_ = false;
  UnmapViewOfFile((const void*)buf_);
  CloseHandle(map_);
 }
}

bool CSS_Mem_Map::send(void *p, size_t size)
{
 if (this->owner_)
 {
  CSS_Stick_Buffer buf(buf_, size);
  buf.copy_unsigned_long(size);
  buf.copy(p, size);

  memcpy((void*)buf_, buf.rd_ptr(), buf.size());
 }

 return false;
}

bool CSS_Mem_Map::recv(void *p, size_t size)
{
 if (this->owner_)
 {
  guard_.acquire();
  CSS_Stick_Buffer buf(buf_, size_);

  size = buf.extract_unsigned_long();
  memcpy(p, buf.rd_ptr(), size);

  return true;
 }

 return false;
}
//////////////////////////////////////////////////////////////


对于初次接触class  CSS_Mem_Map : public CSS_Ipc<CSS_Mem_Map > 的可能觉得有点拗口。

CSS_Ipc<CSS_Mem_Map > 其实只是告诉 CSS_Ipc模板, T类型的名字是 CSS_Mem_Map,不要去联想CSS_Mem_Map的行为, 对于此时的CSS_Ipc来说他只是个名字, 因为还没有调用

展开编译。CSS_Mem_Map 继承了CSS_Ipc 的行为接口。

CSS_Ipc<CSS_Mem_Map > *ipc_map = new CSS_Mem_Map //调用

此时CSS_Ipc 开始展开 以init为例

bool CSS_Ipc::init(const char* name)
{
 CSS_Mem_Map *t = static_cast<CSS_Mem_Map *>(this);
 return t->init(name);
}

CSS_Mem_Map *t = static_cast<CSS_Mem_Map *>(this); 因为CSS_Ipc和CSS_Mem_Map拥有相同的行为, 可以联想 float f; int i = static_cast<float>(f);
float 和 int 具有相同的操作, 只是实现上的不同。(不太确切)

此时 CSS_Mem_Map 
bool CSS_Mem_Map::init(const char* name)
{
 strcpy(this->name_, name);
 map_=(HANDLE)CreateFileMapping((HANDLE)0xFFFFFFFFFFFF,
                             NULL,
           PAGE_READWRITE,
           0,
           this->size_,
           this->name_);

 if (map_)
 {
  buf_=(char *)MapViewOfFile(map_,
                          FILE_MAP_ALL_ACCESS,
           0,0,0);

  this->owner_ = true;
 }

 return this->owner_;
}

即ipc_map 将会调用 CSS_Men_Map::init();

/////////////////////////////////
继承的实现

class CSS_Ipc
{
  virtual boo init(char *name) = 0;
  ......
}

class CSS_Mem_Map : public CSS_Ipc
{
   virtual bool inti (char *name) {...}
}

CSS_Ipc *p = new CSS_Mem_Map;

/////////////////////////////////////

与继承的不同是, 少了虚拟函数指针和指针的转换开销。

//错误之处难免,敬请谅解