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