C++ 共享对象和引用对象的引用计数

C++ 共享对象和引用对象的引用计数,c++,reference-counting,C++,Reference Counting,根据以下对参考计数的描述: “一个普通的“引用计数”习惯用法涉及一个“共享对象””(带有 “计数”和简单的“引用对象< /强>”(不是C++引用, 虽然语义类似),但它们都引用了共享 “引用对象”的构造函数和析构函数 负责调用共享服务器上的incref/decref方法 所以共享对象会自动计算 活动的“引用对象”。() 我在互联网上搜索并发现了以下示例: namespace Optimized { struct StringBuf { StringBuf(); /

根据以下对参考计数的描述:

“一个普通的“引用计数”习惯用法涉及一个“共享对象””(带有 “计数”和简单的“<强>引用对象< /强>”(不是C++引用, 虽然语义类似),但它们都引用了共享 “引用对象”的构造函数和析构函数 负责调用共享服务器上的incref/decref方法 所以共享对象会自动计算 活动的“引用对象”。()

我在互联网上搜索并发现了以下示例:

namespace Optimized {
struct StringBuf {
    StringBuf();             // start off empty
   ~StringBuf();             // delete the buffer
    void Reserve( size_t n );// ensure len >= n

    char*    buf;            // allocated buffer
    size_t   len;            // length of buffer
    size_t   used;           // # chars actually used
    unsigned refs;           // reference count
};

class String {
  public:
    String();                // start off empty
   ~String();                // decrement reference count
                             //  (delete buffer if refs==0)
    String( const String& ); // point at same buffer and
                             //  increment reference count
    void   Append( char );   // append one character
  private:
    StringBuf* data_;
 };
}

  namespace Optimized {

   StringBuf::StringBuf() : buf(0), len(0), used(0), refs(1) { }

   StringBuf::~StringBuf() { delete[] buf; }

   void StringBuf::Reserve( size_t n ) {
    if( len < n ) {
    size_t newlen = max( len * 1.5, n );
    char*  newbuf = new char[ newlen ];
    copy( buf, buf+used, newbuf );

    delete[] buf;   // now all the real work is
    buf = newbuf;   //  done, so take ownership
    len = newlen;
    }
  }

  String::String() : data_(new StringBuf) { }
  String::~String() {
  if( --data_->refs < 1 ) {
    delete data_;
      }
    }
   String::String( const String& other )
    : data_(other.data_)
    {
      ++data_->refs;
    }
 }
名称空间优化{
StringBuf结构{
StringBuf();//开始时为空
~StringBuf();//删除缓冲区
无效保留(大小_tn);//确保长度>=n
char*buf;//分配的缓冲区
size\u t len;//缓冲区的长度
未使用的大小;实际使用的字符数
无符号引用;//引用计数
};
类字符串{
公众:
String();//开始时为空
~String();//递减引用计数
//(如果refs==0,则删除缓冲区)
String(const String&);//指向同一缓冲区和
//增量引用计数
void Append(char);//追加一个字符
私人:
StringBuf*数据;
};
}
名称空间优化{
StringBuf::StringBuf():buf(0),len(0),used(0),refs(1){
StringBuf::~StringBuf(){delete[]buf;}
空字符串BUF::保留(大小\u t n){
if(len参考值<1){
删除数据;
}
}
字符串::字符串(常量字符串和其他)
:数据(其他数据)
{
++数据->参考;
}
}
该示例是否满足上述描述中的条件?我的意思是,它是否涉及共享对象(在这种情况下是StringBuf struct吗?)和引用对象(字符串类)?

将业务逻辑与生命周期管理相结合(几乎是*)从来都不是一个好主意

因此,
C++11标准库
和众所周知的
Boost库
中的引用计数共享所有权在封装最常用所有权方案的单独模板类中实现

Boost库中
有:

  • shared_ptr
    -具有引用计数的共享所有权(创建特定原始指针
    T*
    shared_ptr
    的第一个实例时分配引用计数器)

  • 弱\u ptr
    -一个句柄,如果该句柄仍处于活动状态,则可用于获取完整的
    共享\u ptr

  • *
    侵入式\u ptr
    -具有引用计数的共享所有权,其中引用计数器是被管理对象的一部分。这个特殊的类是您试图实现的一个示例,但是已经达到了行业标准


有点?此处显示的代码在引用计数时起作用,但没有任何参与引用计数的构造函数(即副本),很难确定它是否正确计数。:-)@Xarn我添加了复制构造函数EAH,看起来不错,尽管它完全不安全。@Xarn使用InterlocatedDecrement,refs上的增量足以使其线程安全?我必须用“不知道”来回答这个问题。我不知道
InterlockedIncrement
的语义,我不想猜测。(还请记住,线程安全有各种定义,需要同步的内容取决于为字符串提供的API。对于任何非琐碎的内容,您还需要某种形式的关键部分。(考虑重新配置,通过类似于
[]
操作符的方式访问位置处的字符)您能提到这个问题吗“它是否涉及共享对象(在这种情况下是StringBuf struct吗?)和引用对象(String类)?“您的代码确实实现了引用计数,但与
C++
上下文中的想法完全不同。在
shared\u ptr
中,共享对象将被隐藏并归
template shared\u ptr
所有,引用对象将是
T
,引用对象将不知道引用计数器的任何内容。根据我问题中的上述描述,我们可以将Struct StringBuf视为共享对象,将class String视为引用对象?