Proxy模式设计——引用计数

本文探讨了C++中通过引用计数实现智能垃圾回收的原理及其实现方式,通过内部分析一个实例代码,展示了如何在类中封装资源和方法,以简化内存管理并提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

谈到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 class
class 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.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值