Proxy模式设计——引用计数
来源:互联网 发布:头像源码在线制作 编辑:程序博客网 时间:2024/05/16 09:29
谈到C++的垃圾收集策略,有一个用的比较多的方法就是引用计数在引用计数中,每一个对象负责维护对象所有引用的计数值。当一个新的引用指向对象时,引用计数器就递增,当去掉一个引用时,引用计数就递减。当引用计数到零时,该对象就将释放占有的资源。
试想在某场景种,类A的资源在类B和类C中都被引用,因此如果A不在使用但是B和C还有用时,此时不能释放A;而在释放B和C时只需要消除对A的引用即可;只有当B和C都不再使用A的资源之后,A才能够释放。这样一来,A,B和C在每次释放的时候都需要检查是否有依赖的引用关系,不仅编程麻烦,还降低了效率。
可以思考一下,是否有必要让A知道谁在引用它,答案是没必要,A只需要知道有多少个人在引用它,这样A只需要维护一个计数器,每次添加新的引用时计数器加1,该资源释放时计数器减1,当计数器数值为0时就释放A。
在实际设计代码的时候,可以让包含资源以及方法的类作为内部类,然后在外部用一个含有“智能引用”的计数器以及指向资源的指针的类来封装该类。这样就可以实现一个简单的含有引用计数功能、能够智能收集垃圾的封装类。一个实例代码如下:
#include <iostream>#include <cstring>using namespace std;//outer classclass String {public: //default ctor String() { rep_ = new StringRep(""); cout << "String ctor: (def):" << endl; } //1-arg String( const char* arg ) { rep_ = new StringRep(arg); cout << "String ctor: " << arg << "." << endl; } //copy ctor String( String & str) { //rep_ = new StringRep( *str.rep_ ); rep_ = str.rep_; ++str.rep_->count_; cout << "String ctor (copy): " << str.rep_->str_ << "." << endl; } //dtor ~String() { cout << "String dtor: " << rep_->str_ << ", before decrement, count is " << rep_->count_ << endl; if(--rep_->count_ == 0) delete rep_; } String& operator= ( String &rhs ) { ++rhs.rep_->count_; if(--rep_->count_ == 0) delete rep_; rep_ = rhs.rep_; return *this; } friend ostream& operator << ( ostream&, String& ); //inner class class StringRep { public: //make String a friend of StringRep friend class String; friend ostream& operator << ( ostream&, StringRep& ); StringRep() { cout << " StringRep ctor (def):" << endl; str_ = NULL; //initial count_ count_ = 1; } StringRep( const char* in ) { cout << " StringRep ctor: " << in << '.' << endl; str_ = new char[strlen(in) + 1]; strcpy( str_, in ); count_ = 1; } StringRep( StringRep& str ) { cout << " StringRep ctor (copy): " << str.str_ << '.' << endl; str_ = new char[strlen(str.str_) + 1]; strcpy( str_, str.str_ ); count_ = str.count_; } ~StringRep() { cout << " StringRep dtor: " << str_ << '.' << endl; delete str_; } StringRep& operator= ( StringRep& rhs ) { if (this == &rhs) return *this; delete str_; str_ = new char[strlen(rhs.str_) + 1]; strcpy( str_, rhs.str_ ); return *this; } private: char* str_; //add member data count_ int count_; };private: //a pointer to StringRep StringRep *rep_;};ostream& operator << ( ostream& os, String::StringRep& str ) { return os << str.str_; }ostream& operator << ( ostream& os, String& str ) { return os << *(str.rep_); }int main( void ) { String a( "hello" ); // String b = "world"; is error in my computer String b( "world" ); String c( a ); String d = a; String e; a = b; e = b; cout << "a is " << a << '.' << endl; cout << "b is " << b << '.' << endl; cout << "c is " << c << '.' << endl; cout << "d is " << d << '.' << endl; cout << "e is " << e << '.' << endl; return 0;}编译运行之后可以得到如下的结果:
// StringRep ctor: hello.// String ctor: hello.// StringRep ctor: world.// String ctor: world.// String ctor (copy): hello.// String ctor (copy): hello.// StringRep ctor: .// String ctor (def):// StringRep dtor: .// a is world.// b is world.// c is hello.// d is hello.// e is world.// String dtor: world, before decrement, count is 3// String dtor: hello, before decrement, count is 2// String dtor: hello, before decrement, count is 1// StringRep dtor: hello.// String dtor: world, before decrement, count is 2// String dtor: world, before decrement, count is 1// StringRep dtor: world.
0 0
- Proxy模式设计——引用计数
- 设计模式—Proxy模式
- 设计模式2—Proxy设计模式
- 设计模式——代理模式(Proxy)
- 【设计模式】—— 代理模式Proxy
- C++设计模式——Proxy模式
- 设计模式笔记——Proxy
- 设计模式——代理(Proxy)
- 设计模式2——Proxy设计模式
- 设计模式2——Proxy设计模式
- 【设计模式】结构性模式—— 代理模式(Proxy Pattern)
- 设计模式学习——Proxy代理模式
- NET常用设计模式——代理(Proxy)模式
- 设计模式 Design Parttern ——代理模式Proxy
- 设计模式——代理模式【Proxy Pattern】
- java设计模式之——Proxy:代理模式
- 深入浅出设计模式(8)——Proxy模式
- 设计模式(十三)——代理模式(Proxy)
- Web学习记录<三>小练习.实现一个登录
- MyEclipse8.5 自动生成注册码的破解方法
- 【HDU】4658 Integer Partition【生成函数——数拆分】
- 关于TCP连接数的限制(基于epoll)
- 【C++】cin、cout的效率比scanf和printf低的解决方法
- Proxy模式设计——引用计数
- RGB、HSV、HSI颜色空间
- 解决搜狗输入法无法切换出中文的问题
- ZOJ - 3201 Tree of Tree
- C语言函数调用三种方式:传值调用,引用调用和传地址调用
- <context:component-scan>使用说明
- spring MVC中CommonsMultipartResolver上传文件大小限制,如何对特定请求进行单独设置?
- 编译Rust for arm
- js split 的用法和定义 js split分割字符串成数组的实例代码