【C++模版之旅】项目中一次活用C++模板(traits)的经历
class IContainer
{
public:
virtual RESULT Insert(const std::string& key, const ExportData& data) = 0;
virtual RESULT Delete(const std::string& key) = 0;
virtual RESULT Find(const std::string& key, ExportData& data) = 0;
};
class ExportData
{
public:
long GetData() {
return m_lData;
}
void SetData(long data) {
m_lData = data;
}
string GetData() {
return m_strData;
}
void SetData(string data) {
m_strData = data;
}
// ...... overload the other two types private:
long m_lData;
string m_strData;
// ...... overload the other two types
};
void GetData(long& data) {
data = m_lData;
}
void SetData(long data) {
m_lData = data;
}
void GetData(string& data) {
data = m_strData;
}
void SetData(const string& data) {
m_strData = data;
}
template<typename T>
class ExportData
{
public:
T GetData() {
return m_lData;
}
void SetData(T data) {
m_data = data;
}
private:
T m_data;
};
template<typename T>
class ExportData
{
public:
RESULT GetData(T& data) {
return ERROR;
}
RESULT SetData(const T& data) {
return ERROR;
}
};
template<>
class ExportData<long>
{
public:
RESULT GetData(long& data) {
data = m_data;
return OK;
}
RESULT SetData(const long& data) {
m_data = data;
return OK;
}
private:
long m_data;
}; template<>
class ExportData<double>
...... // just like the implementation of long
template<>
class ExportData<string>
...... // just like the implementation of long
template<>
class ExportData<Binary>
...... // just like the implementation of long
template<typename T>
struct TypeTraits
{
static const DATA_TYPE field_type = TYPE_UNSUPPORTED;
};
template<>
struct TypeTraits<std::string>
{
static const DATA_TYPE field_type = TYPE_UTF8;
};
template<>
struct TypeTraits<long>
{
static const DATA_TYPE field_type = TYPE_INEGER;
};
template<>
struct TypeTraits<double>
{
static const DATA_TYPE field_type = TYPE_REAL;
};
template<>
struct TypeTraits<Binary>
{
static const DATA_TYPE field_type = TYPE_BINARY;
};
TypeTraits<long>::field_type == TYPE_UNSUPPORTED
template<typename T>
class ExportData
{
public:
RESULT GetData(T& data) {
return ERROR;
}
RESULT SetData(const T& data) {
return ERROR;
}
};
template<>
class ExportData<long>
{
public:
RESULT GetData(long& data) {
if (TypeTraits<long>::field_type == TYPE_UNSUPPORTED) {
return ERROR;
}
data = m_data;
return OK;
}
RESULT SetData(const long& data) {
m_data = data;
return OK;
}
private:
long m_data;
};
class IContainer
{
public:
template<typename T>
virtual RESULT Insert(const std::string& key, const ExportData<T>& data) = 0; virtual RESULT Delete(const std::string& key) = 0; template<typename T>
virtual RESULT Find(const std::string& key, ExportData<T>& data) = 0;
};
而IContainer本身不是仅仅跟某个类型相关的,也就是不可能把IContainer定义成模板类。怎么办呢?
class ExportData
{
public:
ExportData() : _data(NULL), _size(0){}
ExportData(const ExportData& data) {
_data = NULL;
_size = 0;
AssignData(data._data, data._size);
_type = data._type;
}
~ExportData() {
if (_data) {
delete[] _data;
_data = NULL;
}
}
ExportData& operator=(const ExportData& data) {
this->AssignData(data._data, data._size);
this->_type = data._type;
return *this; template<typename T>
RESULT SetData(const T& data) {
if (TypeTraits<T>::field_type == TYPE_UNSUPPORTED) {
return ERROR;
}
AssignData((const char*)&data, sizeof(T));
_type = TypeTraits<T>::field_type;
return OK;
}
template<>
RESULT SetData<std::string>(const std::string& data) {
AssignData(data.c_str(), data.size());
_type = TYPE_UTF8;
return OK;
}
template<>
RESULT SetData<Binary>(const Binary& data) {
AssignData(data.GetBlobAddr(), data.GetSize());
_type = TYPE_BLOB;
return OK;
} template<typename T>
RESULT GetData(T& data) const {
if (TypeTraits<T>::field_type == TYPE_UNSUPPORTED ||
_data == NULL ||
TypeTraits<T>::field_type != _type) {
return ERROR;
}
memcpy(&data, _data, _size);
return OK;
}
template<>
RESULT GetData<std::string>(std::string& data) const {
if (TYPE_UTF8 != _type || _data == NULL) {
data = "";
return ERROR;
}
data.assign(_data, _size);
return OK;
}
template<>
RESULT GetData<Binary>(Binary& data) const {
if (TYPE_BLOB != _type || _data == NULL) {
data.SetBlobData(NULL, 0);
return ERROR;
}
data.SetBlobData(_data, _size);
return OK;
}
private:
void AssignData(const char* data, unsigned int size) {
if (_data) {
delete[] _data;
_data = NULL;
}
_size = size;
_data = new char[size];
memcpy(_data, data, _size);
}
char* _data;
unsigned long _size;
DATA_TYPE _type;
};
ExportData data;
RESULT res = OK;
res = data.SetData<string>("DataTest");
assert(OK == res); string str;
res = data.GetData<string>(str);
assert(OK == res); res = data.SetData<long>(111);
long ldata = 0;
res = data.GetData<long>(ldata);
assert(OK == res);
【C++模版之旅】项目中一次活用C++模板(traits)的经历的更多相关文章
- 【C++模版之旅】项目中一次活用C++模板(traits)的经历 -新注解
问题与需求: 请读者先看这篇文章,[C++模版之旅]项目中一次活用C++模板(traits)的经历. 对于此篇文章提出的问题,我给出一个新的思路. talking is cheap,show me t ...
- 在使用vue+webpack模版创建的项目中使用font-awesome
前言:最近使用vue+webpack进行一个小项目的开发,按照官方模版文档完成项目初始化后打算引入ont-awesome字体图标库进行使用,引入过程中遇到一些问题并解决,现记录如下. 一开始进展很顺利 ...
- 控制反转和spring在项目中可以带来的好处
Spring实例化Bean的三种方式分别是: 1,xml配置使用bean的类构造器 <bean id="personService" class="cn.servi ...
- 采用EntLib5.0(Unity+Interception+Caching)实现项目中可用的Caching机制
看了园子里很多介绍Caching的文章,多数都只介绍基本机制,对于Cache更新和依赖部分,更是只简单的实现ICacheItemRefreshAction接口,这在实际项目中是远远不够的.实际项目中, ...
- Android项目中如何用好构建神器Gradle?(转)
最近在忙团队并行开发的事情,主要是将各个团队的代码分库,一方面可以降低耦合,为后面模块插件化做铺垫,另一方面采用二进制编译,可以加快编译速度.分库遇到了一些问题,很多都要通过Gradle脚本解决,所以 ...
- 如何在cocos2d项目中enable ARC
如何在cocos2d项目中enable ARC 基本思想就是不支持ARC的代码用和支持ARC的分开,通过xcode中设置编译选项,让支持和不支持ARC的代码共存. cocos2d是ios app开发中 ...
- 关于如何正确地在android项目中添加第三方jar包
在android项目中添加第三方jar包虽然不是一个很复杂的问题,但是确实给很多开发者带来了不小的困扰.我自己就曾经碰到过calss not found exception.error inflati ...
- 项目中如何使用babel6详解
由于浏览器的版本和兼容性问题,很多es6,es7的新的方法都不能使用,等到可以使用的时候,可能已经过去了很多年.Babel可以把es6,es7的新代码编译成兼容绝大多数的主流浏览器的代码. 本篇文章主 ...
- 剑指Offer——企业级项目中分层的含义与依据及多态的优势
剑指Offer--企业级项目中分层的含义与依据及多态的优势 关于以上两点,由于项目经验较少,自己不是很明白,特整理如下. 常见分层架构模式 三层架构 3-tier architecture 微 ...
随机推荐
- "UBUNTU: SAUCE: apparmor: 3.0 backport of apparmor3"
下面提供的commit是为了让nexus 4g的内核支持ubunt touch的一些功能. 链接地址如下: "UBUNTU: SAUCE: apparmor: 3.0 backport of ...
- Thinkphp编辑器扩展类kindeditor用法
一, 使用前的准备. 使用前请确认你已经建立好了一个Thinkphp站点项目. 1,Keditor.class.php和JSON.class.php 是编辑器扩展类文件,将他们拷贝到你的站点项目的Th ...
- HTML5_表单元素
<!DOCTYPE html> <hmtl> <html lang="zh-cn"> <head> <meta charse ...
- repeater操作
protected void rpRole_ItemDataBound(object sender, RepeaterItemEventArgs e) { if (e.Item.ItemType == ...
- JDBC batch批量Statement executeBatch 详细解释
JDBC提供了数据库batch处理的能力,在数据大批量操作(新增.删除等)的情况下能够大幅度提升系统的性能.我曾经接触的一个项目,在没有採用batch处理时,删除5万条数据大概要半个小时左右,后来对系 ...
- Codeforces Round #256 (Div. 2) D. Multiplication Table 二分法
D. Multiplication Table time limit per test 1 second memory limit per test 256 megabytes input st ...
- schedule vs scheduleAtFixedRate
最好的方法是在两者之间区分 timer灵感时间设定过去时间T,scheduleAtFixedRate将从T现在所有的任务中运行,schedule而该任务将只运行从现在开始计时. public clas ...
- NYOJ 118 路方案(第二小的跨越)
修路方案 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描写叙述 南将军率领着很多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N.因为交通不太便利,南将军准备修 ...
- Linux鸟哥的私房菜(3)— 总体规划和磁盘分区 读书笔记
1.每个硬件设备Linux中的文件名称 在Linux系统中.每一个设备都被当成一个文件来对待.而且差点儿全部的硬件设备文件都在/dev文件夹下 常见设备与其对于文件名称 2.磁盘连接的方式与设备文件名 ...
- c#获取页面重定向url
/// <summary> /// 获取页面重定向url /// </summary> /// <param name="url"></p ...