more effective c++——Item M29 引用计数(二)带静态成员变量的rfstring类实现

more effective c++——Item M29 引用计数(一)简略的rfstring类设计和写时拷贝
这篇博客中所实现的引用计数还存在未解决的问题——如何通过相同的值多次构造rfstring对象时,防止多次在堆上分配内存?

可以通过在rfstring类中添加一个static list

// static_rfstring.h
#pragma once
#include <list>
using namespace std;
class static_rfstring
{
public:
    static_rfstring(const char *str);
    static_rfstring(const static_rfstring & rhl);

    static_rfstring & operator=(const char *str);

    static_rfstring & operator=(const static_rfstring & rhl);

    ~static_rfstring();

private:
    class stringvalue
    {
    public:
        stringvalue(const char *str);
        ~stringvalue();

        char *value;
        int rfcount;
    };

    stringvalue *strvalue;
    static list<stringvalue *> strvaluelist;
};
// static_rfstring.cpp
#include "static_rfstring.h"



std::list<static_rfstring::stringvalue *> static_rfstring::strvaluelist;


static_rfstring::static_rfstring(const char *str)
{
    // 查找字符串是否已经存在
    for (std::list<static_rfstring::stringvalue *>::iterator it = strvaluelist.begin();it != strvaluelist.end();++it)
    {
        if ((strlen((*it)->value) == strlen(str)) && (0 == strcmp(str, (*it)->value)))
        {
            (*it)->rfcount++;
            strvalue = *it;
            return;
        }
    }

    // 不存在则新构建个stringvalue对象
    strvalue = new stringvalue(str);
    strvaluelist.push_back(strvalue);
}

static_rfstring::static_rfstring(const static_rfstring & rhl)
{
    strvalue = rhl.strvalue;
    strvalue->rfcount++;
}

static_rfstring & static_rfstring::operator=(const char *str)
{
    if (--strvalue->rfcount == 0)
    {
        delete strvalue;
    }
    for (std::list<static_rfstring::stringvalue *>::iterator it = strvaluelist.begin(); it != strvaluelist.end(); ++it)
    {
        if ((strlen((*it)->value) == strlen(str)) && (0 == strcmp(str, (*it)->value)))
        {
            (*it)->rfcount++;
            strvalue = *it;
            return *this;
        }
    }

    // 新构建一个stringvalue对象
    strvalue = new stringvalue(str);
    strvaluelist.push_back(strvalue);
    return *this;
}

static_rfstring & static_rfstring::operator=(const static_rfstring & rhl)
{
    if (this == &rhl)
    {
        return *this;
    }
    if (--strvalue->rfcount == 0)
    {
        delete strvalue;
    }

    strvalue = rhl.strvalue;
    strvalue->rfcount++;
    return *this;
}

static_rfstring::~static_rfstring()
{
    for (std::list<static_rfstring::stringvalue *>::iterator it = strvaluelist.begin(); it != strvaluelist.end(); ++it)
    {
        if ((*it) == strvalue)
        {
            if (--(*it)->rfcount == 0)
            {
                strvaluelist.remove(strvalue);
                delete strvalue;
            }
            return;
        }
    }
}


static_rfstring::stringvalue::stringvalue(const char *str):rfcount(1)
{
    value = new char[strlen(str) + 1];
    strcpy(value, str);
}

static_rfstring::stringvalue::~stringvalue()
{   
    delete value;
    value = nullptr;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值