代理设计模式在auto_ptr及smart_ptr中的体现
下面这段代码是auto_ptr的实现:
class Image
{
public:
Image(string name): m_imageName(name) {}
virtual ~Image() {}
virtual void Show() {}
protected:
string m_imageName;
};
class BigImage: public Image
{
public:
BigImage(string name):Image(name) {}
~BigImage() {}
void Show() { cout<<"Show big image : "<<m_imageName<<endl; }
};
class BigImageProxy: public Image
{
private:
BigImage *m_bigImage;
public:
BigImageProxy(string name):Image(name),m_bigImage() {}
~BigImageProxy() { delete m_bigImage; }
void Show()
{
if(m_bigImage == NULL)
m_bigImage = new BigImage(m_imageName);
m_bigImage->Show();
}
};
阅读上面的代码,我们可以发现 auto_ptr 类就是一个代理,客户只需操作auto_prt的对象,而不需要与被代理的指针pointee打交道。auto_ptr 的好处在于为动态分配的对象提供异常安全。因为它用一个对象存储需要被自动释放的资源,然后依靠对象的析构函数来释放资源。这样客户就不需要关注资源的释放,由auto_ptr 对象自动完成。实现中的一个关键就是重载了解引用操作符和箭头操作符,从而使得auto_ptr的使用与真实指针类似。
我们知道C++中没有垃圾回收机制,可以通过智能指针来弥补,下面给出智能指针的一种实现,采用了引用计数的策略。
template <typename T>
class smart_ptr
{
public:
smart_ptr(T *p = ): pointee(p), count(new size_t()) { } //初始的计数值为1
smart_ptr(const smart_ptr &rhs): pointee(rhs.pointee), count(rhs.count) { ++*count; } //拷贝构造函数,计数加1
~smart_ptr() { decr_count(); } //析构,计数减1,减到0时进行垃圾回收,即释放空间
smart_ptr& operator= (const smart_ptr& rhs) //重载赋值操作符
{
//给自身赋值也对,因为如果自身赋值,计数器先减1,再加1,并未发生改变
++*count;
decr_count();
pointee = rhs.pointee;
count = rhs.count;
return *this;
}
//重载箭头操作符和解引用操作符,未提供指针的检查
T *operator->() { return pointee; }
const T *operator->() const { return pointee; }
T &operator*() { return *pointee; }
const T &operator*() const { return *pointee; }
size_t get_refcount() { return *count; } //获得引用计数器值
private:
T *pointee; //实际指针,被代理
size_t *count; //引用计数器
void decr_count() //计数器减1
{
if(--*count == )
{
delete pointee;
delete count;
}
}
};
本文出处:http://blog.csdn.net/wuzhekai1985
代理设计模式在auto_ptr及smart_ptr中的体现的更多相关文章
- OC学习——OC中的@protocol(@required、@optional)、代理设计模式
一.什么是协议? 1.协议声明了可以被任何类实现的方法 2.协议不是类,它是定义了一个其他对象可以实现的接口 3.如果在某个类中实现了协议中的某个方法,也就是这个类实现了那个协议. 4.协 ...
- IOS之Objective-C学习 代理设计模式
鉴于Objective-C是不支持多继承的,所以需要用协议来代替实现其他类的方法,所以有了代理设计模式. 代理,又称委托,delegation. 代理模式可以让一个单继承的类实现父类以外其他类的方法. ...
- 你真的了解iOS代理设计模式吗?
在项目中我们经常会用到代理的设计模式,这是iOS中一种消息传递的方式,也可以通过这种方式来传递一些参数.这篇文章会涵盖代理的使用技巧和原理,以及代理的内存管理等方面的知识.我会通过这些方面的知识,带大 ...
- Objective-C之代理设计模式小实例
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- 【转】你真的了解iOS代理设计模式吗?
转自:http://www.cocoachina.com/ios/20160317/15696.html 在项目中我们经常会用到代理的设计模式,这是iOS中一种消息传递的方式,也可以通过这种方式来传递 ...
- ios代理设计模式
代理设计模式的作用: 1.A对象监听B对象的一些行为,A成为B的代理 2.B对象想告诉A对象一些事情,A成为B的代理 代理设计模式的总结: 如果你想监听别人的一些行为,那么 ...
- 静态代理设计模式(StaticProxy)
静态代理设计模式: 要求:真实角色,代理角色:真实角色和代理角色要实现同一个接口,代理角色要持有真实角色的引用. 在Java中线程的设计就使用了静态代理设计模式,其中自定义线程类实现Runable接口 ...
- 代理设计模式 (静态代理设计模式)+ 动态代理(JDK和Cglib)
一.代理设计模式 1.设计模式:前人总结一套解决特定问题的代码 2.代理设计模式优点: 2.1 保护真实对象 2.2 让真实对象职责更明确 2.3 扩展 3.代理设计模式 3.1 真实对象(老总) 3 ...
- Java 设计模式六原则及23中常用设计模式
一.设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接 ...
随机推荐
- myeclipse 修改用户名密码
当在一台公共的电脑上开发程序时,就需要涉及到更改svn用户名和密码,不然直接用本机用户密码提交,有点不妥. win7系统解决方案: C:\Documents and Settings\Administ ...
- 无线局域网(WLAN)
无线局域网根据结构可以分为两大类:有固定基础设施的无线局域网和无固定基础设施的局域网. 有固定基础设施是指网络中已经预先存在了一批固定的数据处理和转发设备,这些固定设备可以通过有线方式连接其他网络或 ...
- web.1
<!DOCTYPE html><html><head><meta charset="utf-8"> <title>毛哥调 ...
- Openflow协议详解
http://www.h3c.com/cn/d_201811/1131080_30005_0.htm# 1 OpenFlow背景 转发和控制分离是SDN网络的本质特点之一 .在SDN网络架构中,控制平 ...
- HslCommunication组件库使用说明 (转载)
一个由个人开发的组件库,携带了一些众多的功能,包含了数据网络通信,文件上传下载,日志组件,PLC访问类,还有一些其他的基础类库. nuget地址:https://www.nuget.org/packa ...
- 大数据学习-2 认识Hadoop
一.什么是Hadoop? Hadoop可以简单的理解为一个数据存储和数据分析分布式系统.随着互联网的普及产生的数据是非常的庞大的,那么我们怎么去处理这么大量的数据呢?传统的单一计算机肯定是完成不了的, ...
- 2.4 逻辑运算符 &&(与)、||(或)、非(!)
一.逻辑运算符 &&(与).||(或).非(!) 逻辑运算符两边的表达式一定是布尔值,结果也是布尔值. 1.1.1 逻辑与 && => 表示并且.且的意思: tr ...
- maven 使用axis2 client 需要导入的依赖
<dependency> <groupId>org.apache.axis2</groupId> <artifactId>axis2</artif ...
- 2018.5.4 Unix的五种IO模型
阻塞非阻塞和异步同步 同步和异步关注的是消息通信机制,关注两个对象之间的调用关系. 阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态,关注单一程序. Unix的五种IO模型 以下基于Li ...
- 让Entity Framework不再私闯sys.databases
这里的“私闯sys.databases”是指Entity Framework默认发起的查询:SELECT Count(*) FROM sys.databases WHERE [name]=N'数据库名 ...