Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > C/C++ > shared_ptr 两种常见的使用方式 (1)
【标  题】:shared_ptr 两种常见的使用方式 (1)
【关键字】:shared_ptr
【来  源】:http://blog.csdn.net/rogeryi/archive/2007/01/22/1489804.aspx

shared_ptr 两种常见的使用方式 (1)

Your Ad Here
Roger(roger2yi@gmail.com
1. 当作类对象的“共享句柄”来使用
2. 在类内部提供资源管理服务 —— “为类提供资源的共享拷贝语义(或称为浅拷贝shadow copy,并在正确的时间回收资源”
 
上述的两种方式一种是在类外部使用,一种是在类内部使用,然而这两种方式并不是非此即彼的关系,很多情况下我们都可以选择任意一种,选择其中一种理由通常是遵循“更容易被使用,更难以被误用”的原则。
 
当作类对象的“共享句柄”来使用
 
在这种使用方式下,结合Create Method模式使用会取得更好的效果(关于Create Method模式,更多信息请看“模式与重构一书”)
 
以下是一个使用场景,我们有一个类,类封装了一个底层资源的句柄和跟句柄相关的所有API调用(句柄和API调用来自操作系统或者其它的C函数库)
 
句柄在不再被使用的时候需要被释放(析构函数是最适合做这件事的,不是吗?);
 
句柄的拷贝可能是一种危险的行为(通常句柄的实现都是所谓的Opaque pointer 不透明指针,也是说该指针实际是指向一块API操作的数据结构,只是该数据结构是不对外公开的,这也是所谓的COO风格),因为有可能导致悬挂句柄(其实也是悬挂指针)或者由于释放的责任模糊而导致重复释放。
 
所以,我们用类封装底层资源句柄,但不为该类提供拷贝行为,而是通过外裹的share_ptr来提供共享拷贝语义。
 
下面是一个实际例子,来自我自己封装lcms库profile句柄的一个类lcms是一个开源用于色彩管理的C函数库,也是一个轻量级可用于学习C-OO编程的不错选择),cmsHPROFILE是lcms的profile(特性文件)资源句柄。
 
KProfile.h
 
 
#pragma once
#include 
"KProfileShPtr.h"
 
#include 
<lcms/lcms.h>
 
namespace milk
{
    
/** The wrapper class of lcms's profile,
       group related function together,
       and use RAII idiom to manage resource. 
*/
    
class PUREMILK_EXPORT KProfile : private boost::noncopyable
    {
    
public:
       
~KProfile(void);
       
/** Create method, more information please refer to book
           - Refactoring to Patterns. 
*/
 
       
/** Three basic create methods, from an existing handle,
           file and memory. 
*/
       
static KProfileShPtr createFromHandle(cmsHPROFILE);
       
static KProfileShPtr createFromFile(const char*const char*);
       
static KProfileShPtr createFromMemory(void*, UINT32);
 
       
/** Get the internal profile handle of lcms. */
       cmsHPROFILE getHandle() 
const {return handle_;}
 
       
/** Print out */
       ostream
& print(ostream&const;
 
       
/** Basic information related function. */
       
string               getProductName() const;
       
string               getProductDescription() const;
       
string               getProductInformation() const;
       
string               getManufacturer() const;
       
string               getModel() const;
       
string               getCopyright() const;
       UINT32               getProfileVersion() 
const;
       
string               getProfileVersionString() const;
 
    
private:
       KProfile();
       KProfile(cmsHPROFILE);
       KProfile(
const char*const char*);
       KProfile(
void*, UINT32);
 
       cmsHPROFILE       handle_;
    };
}
1.         KProfile 封装了cmsHPROFILEhandle_句柄,和许多相关的lcms API调用
2.         从boost库的noncopyable获得禁止拷贝的行为(拷贝构造函数和赋值操作符)
3.         KProfile不提供public的构造函数,而是提供一系列的create methods,所有的create methods都返回KProfileShPtrtypedef boost::shared_ptr<KProfile> KProfileShPtr
4.         getHandle函数会返回内部profile句柄(资源封装类应该允许返回内部的句柄或者指针,参看Effective C++第三版)
 
KProfileShPtr.h
 
#pragma once 
 
namespace milk
{
    
/** Shared pointer for KProfile. */
    
class KProfile;
    typedef boost::shared_ptr
<KProfile>       KProfileShPtr;
}
 
1.    另外提供一个KProfileShPtr.h而不把typedef置于KProfile.h内的原因是为了提供KProfileShPtr的前置声明(类似C++标准库iosfwd的做法),就是说当其它类的接口需要使用到KProfileShPtr的时候,它不必在头文件中包括KProfile.h,而只需要包括KProfileShPtr.h即可。(当然在所有的地方都写boost::shared_ptr<KProfile>可以免除这种麻烦,看个人喜好)
 
KProfile.cpp
 
#include "KProfile.h"
#include 
"KCMSException.h"
 
namespace milk
{
    KProfile::KProfile()
       : handle_(
0)
    {
    }
 
    KProfile::KProfile(cmsHPROFILE handle)
       : handle_(handle)
    {
    }
 
    KProfile::
~KProfile(void)
    {
       
if (this->handle_)
           cmsCloseProfile(
this->handle_);
    }
 
    KProfileShPtr
    KProfile::createFromHandle(cmsHPROFILE handle)
    {
       KProfile
* profile = new KProfile(handle);
       
return KProfileShPtr(profile);
    }
}
 
1. 在析构函数中会释放profile句柄
2. 由于KProfile没有提供拷贝行为,所以析构函数不会担心会多次释放同一句柄,当然如果释放发生在类外部,这不是类KProfile可以控制的
 
 
 
 
seekg无效?:【上一篇】
看了看COM编程:【下一篇】
【相关文章】
  • auto_ptr与shared_ptr --- shared_ptr (2)
  • auto_ptr与shared_ptr --- auto_ptr (1)
  • 5年后的OGRE3D,与从其中SHARED_PTR谈开
  • 【随机文章】
  • 禁止添加打印机
  • SVG + Javascript + ASP.NET + WebService开发楼宇管理系统(四)
  • 中华人民共和国计算机软件保护条例摘抄
  • .NET 2.0 之 MSBuild 初体验
  • Horizon Occlusion Culling
  • 2004版点点通看电影
  • 字符串搜索函数
  • VC面试题
  • 经典问题WTO
  • 在USB盘上打造自己的Linux发行版
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 bbb软讯网络 All Rigths Reserved.