首先本文并不是讲解C++萃取技术,关于C++的萃取技术网上有很多文章,推荐http://www.cppblog.com/woaidongmao/archive/2008/11/09/66387.html如果这篇文章能看懂肯定也能看懂我这篇小博文了。

熟悉C++的人肯定都用过auto_ptr这个智能指针,其原理就是在auto_ptr构造的时候将申请到的内存地址放进该对象的内部保存,而这个对象析构的时候则调用delete释放之前申请的内存,这样不仅仅省去了程序员时刻关注何时释放内存的顾忌,同时即使是程序在new和delete中间发生异常被捕获内存仍然会释放不会有泄漏。同时也可以做引申,可以自己写一个类,里面保存临界区对象,当对象创建时进入临界区,而对象析构的时候自从释放临界区,这样也可以保证进临界区和出临界区中间发生异常后锁仍然会释放,在一部分情况下保证程序不会有太大的异常。相关伪代码如下:

 class CAutoLock
{
public:
CAutoLock(LPCRITICAL_SECTION lpCriticalSection)
{
m_lpCriticalSection = lpCriticalSection;
EnterCriticalSection(m_lpCriticalSection);
}
~CAutoLock(){LeaveCriticalSection(m_lpCriticalSection); }
private:
LPCRITICAL_SECTION m_lpCriticalSection;
};

好了,锁和智能指针都有了,但是如果想类似让一个文件句柄HANDLE一样在遇到return时关闭掉,该怎么做呢?其实自己实现一个类似auto_ptr,将内存地址换成文件句柄就可以了,但是如果又遇到一个SOCKET呢?其实可以用模板偏特化搞定。但是我现在介绍一种利用C++萃取技术,用一个主体类再加上一些辅助类完成以上功能。其原理也很简单,利用C++萃取技术,自动识别需要释放的数据类型,然后根据不同的数据类型选择不同的释放方式。相关代码如下:

 #pragma once
#include <windows.h>
#include <Winsock2.h> #pragma comment(lib,"Ws2_32.lib") /*************************************************
示例程序能够识别的类型:
第一为基础句柄(为用CloseHandle释放的)
第二个为网络通信SOCKET,需要用closesocket释放
可以根据实际需要自己添加实现,例子程序就只实现这两个功能
*************************************************/ //基础句柄类(CloseHandle释放类型)
class CCommomHandleObject
{
public:
void clear(HANDLE hCommhandle)
{
if (INVALID_HANDLE_VALUE != hCommhandle)
{
CloseHandle(hCommhandle);
}
}
}; //套接字类(closesocket释放类型)
class CSOCKETObject
{
public:
void clear(SOCKET m_hSocket)
{
if (INVALID_SOCKET != m_hSocket)
{
closesocket(m_hSocket);
}
}
}; //C++萃取基础类
template<class _xTypeShow>
class CTraitsBaseObject
{
}; //根据HANDLE识别出CCommomHandleObject类
template<>
class CTraitsBaseObject<HANDLE>
{
public:
typedef CCommomHandleObject _data_type_show;
}; //根据SOCKET识别出CSOCKETObject
template<>
class CTraitsBaseObject<SOCKET>
{
public:
typedef CSOCKETObject _data_type_show;
};
/****************************************************************************
资源释放类,本例的重点,需要根据每个须释放的资源绑定一个CContainerClass对象
然后对象析构时会根据CTraitsBaseObject<_xType>::_data_type_show识别出是否为
自己认识的数据类型,如不认识则直接报错,然后创建临时对象调用clear,
根据实际情况销毁绑定的资源。
****************************************************************************/
template<class _xType>
class CContainerClass
{
public:
CContainerClass(_xType &_tay ){m_hTay = _tay;}
~CContainerClass(void){clear();}
private:
CContainerClass(){}
CContainerClass(CContainerClass &tay){} void clear()
{
CTraitsBaseObject<_xType>::_data_type_show().clear(m_hTay);
}
private:
_xType m_hTay;
};

以上代码只是完成了需要用CloseHandle释放的句柄和SOCKET两种资源类型,需要增加时只需增加相信的类型即可。而资源申请后创建一个CContainerClass对象,选择对应的类型将两者绑定即可。实际应用代码如下:

 int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hFileFile = CreateFile(_T("D:\\Program Files\\小软件\\jpskb.exe"), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
CContainerClass<HANDLE> hContainerClassFile(hFileFile); SOCKET sock = INVALID_SOCKET;
CContainerClass<SOCKET> sContainerClasssock(sock); int i = ;
//CContainerClass<int> iCContainerClassi(i); //int为不识别类型,编译不过
return ;
}

本来想过需不需要把不识别的类型做成一个空的clear函数,就是遇到不认识的类型什么都不做直接跳过。但是后来想想要是这样如果遇到没有对应的资源销毁类恐怕会有内存泄漏,于是让程序遇到不认识的类型直接编译不过即可。

其实写这篇文章有点多此一举,因为实际开发中根本不需要这么做。但是萃取技术作为C++当中一个比较难懂的知识点,如果能设计一个实际用途方案对深入理解还是很有帮助的,所以我感觉并非画蛇添足了。

C++萃取技术的一个简单初探的更多相关文章

  1. C++的类型萃取技术

    应该说,迭代器就是一种智能指针,因此,它也就拥有了一般指针的所有特点——能够对其进行*和->操作.但是在遍历容器的时候,不可避免的要对遍历的容器内部有所了解,所以,设计一个迭代器也就自然而然的变 ...

  2. C++11中的技术剖析(萃取技术)

    从C++98开始萃取在泛型编程中用的特别多,最经典的莫过于STL.STL中的拷贝首先通过萃取技术识别是否是已知并且支持memcpy类型,如果是则直接通过内存拷贝提高效率,否则就通过类的重载=运算符,相 ...

  3. 利用JSP编程技术实现一个简单的购物车程序

    实验二   JSP编程 一.实验目的1. 掌握JSP指令的使用方法:2. 掌握JSP动作的使用方法:3. 掌握JSP内置对象的使用方法:4. 掌握JavaBean的编程技术及使用方法:5. 掌握JSP ...

  4. 利用HTML5与jQuery技术创建一个简单的自动表单完成

    来源:GBin1.com 在线演示   在线下载 谷歌快速搜索自带大量自动完成插件——库中甚至还有一个附带的jQuery UI共享选项.然而今天我要寻找一个替代的解决方案.由DevBridge开发的j ...

  5. C++之萃取技术(traits)

    为什么需要类型萃取(特化) 前面我们提到了迭代器,它是一个行为类似于smart pointer之类的东西,主要用于对STL容器中的对象进行访问,而且不暴露容器中的内部结构,而迭代器所指对象的型别称为该 ...

  6. CGI 萃取技术 __type_traits

    前言 上一篇文章讲了 iterator_traits 的编程技法,非常棒适度弥补了 C++ 语言的不足. STL 只对迭代器加以规范,制定了 iterator_traits 这样的东西. CGI 把这 ...

  7. Docker容器技术-创建一个简单的Web应用

    一.创建一个简单的Web应用 1.identicon 基于某个值而自动产生的图像,这个值是IP地址或用户名的散列值. 用途: 通过计算用户名或IP地址的散列值,在网站上提供用于识别用户的图像,以及自动 ...

  8. 自适应游标共享技术02(一个简单的例子来走近ACS)

    为了不让其他因素干扰实验,参数设置如下: optimizer_mode=ALL_ROWS(使用CBO) optimizer_features_enable=11.2.0.3(使用最新的优化参数) op ...

  9. STL源代码分析--萃取编程(traits)技术的实现

    1.为什么要出现? 依照默认认定.一个模板给出了一个单一的定义,能够用于用户能够想到的不论什么模板參数!可是对于写模板的人而言,这样的方式并不灵活.特别是遇到模板參数为指针时,若想实现与类型的參量不一 ...

随机推荐

  1. 零基础入门学习python--第一章

    知识点汇总1. Python的应用范围:操作系统.3D动画.WEB.企业应用.云计算等.2. Python是什么类型的语言?脚本语言,即电脑编程语言,比C.C++或java之类的系统编程语言简单容易. ...

  2. 【CF516D】Drazil and Morning Exercise

    题目 首先我们知道,在树上距离一个点最远的点一定是直径的两个端点之一 首先两遍\(\rm dfs\)把直径求出来,定义\(d(u)\)表示点\(u\)距离其最远点的距离,有了直径我们就能求出\(d\) ...

  3. table 单列宽度设置

    参考:https://blog.csdn.net/lunhui1994_/article/details/81120579 效果: html: <!DOCTYPE html> <ht ...

  4. PHP出现报警后需要修改 date.timezone 的值(php.ini)

    PHP调试的时候出现了警告: It is not safe to rely on the system解决方法,其实就是时区设置不正确造成的,本文提供了3种方法来解决这个问题. 实际上,从PHP 5. ...

  5. PHP算法之回文数

    判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121输出: true示例 2: 输入: -121输出: false解释: 从左向右读, ...

  6. Vultr IP被墙该怎么办

    我们创建好Vultr服务器时候,首先需要检测IP地址是否可用,很多IP在国内被墙,导致使用Xshell连接不上,虽然IP能够ping通,但是SSH依然连接不上.那Vultr IP被墙该怎么办呢? 方法 ...

  7. wordpress 获取所有管理员的邮箱

    function get_administrator_email(){ $blogUsers = get_users('role=Administrator'); $adminEmails = arr ...

  8. Windows Server 2003服务器清理C盘空间的资料多个解决方法

    一.关闭IIS HTTPRERR日志功能 默认情况下,2003服务器会把所有IIS访问错误的记录写入 C:WINDOWSsystem32LogFilesHTTPERR 下的 log 文件中,如果访问量 ...

  9. 锁定文件失败 打不开磁盘“D:\vms\S1\CentOS 64 位.vmdk”或它所依赖的某个快照磁盘(强制关机后引起的问题)

    电脑强制关机后,centos系统启动失败,报异常:锁定文件失败 打不开磁盘“D:\vms\S1\CentOS 64 位.vmdk”或它所依赖的某个快照磁盘.解决办法:进入D:\vms\S1目录,删除下 ...

  10. go网络库cellent实现socket聊天功能

    一 .介绍 cellnet是一个组件化.高扩展性.高性能的开源服务器网络库 git地址:https://github.com/davyxu/cellnet 主要使用领域: 游戏服务器 方便定制私有协议 ...