• 带引用计数的String类简单实现


    很好的一个示范例子,设计到类设计,模版,继承,封装。

    麻雀虽小五脏俱全,废话少说,来看代码:

    主程序:

     1 #include <iostream>
     2 
     3 #include "rcstring.h"
     4 
     5 int main(void)
     6 {
     7     String s("hello");
     8 
     9     std::cout << s[2] << std::endl;
    10 
    11     std::cout << "Hello World!" << std::endl;
    12 
    13     return 0;
    14 }

    String声明和实现:

     1 //rcstring.h
     2 #include "rcobject.h"
     3 #include "rcptr.h"
     4 
     5 class String {
     6 public:
     7     String(const char *value = "");
     8     const char& operator[] (int index) const;
     9     char & operator[] (int index);
    10 private:
    11     struct StringValue: public RCObject {
    12         StringValue(const char *initValue);
    13         StringValue(const StringValue &rhs);
    14         ~StringValue();
    15 
    16         void init(const char *initValue);
    17 
    18         char *data;
    19     };
    20 
    21     RCPtr<StringValue> value;
    22 };
    23 
    24 //rcstring.cpp
    25 #include "rcstring.h"
    26 #include <cstring>
    27 
    28 String::String(const char *initValue)
    29     :value(new StringValue(initValue))
    30 {
    31 
    32 }
    33 
    34 const char& String::operator[] (int index) const
    35 {
    36     return value->data[index];
    37 }
    38 
    39 char& String::operator[] (int index)
    40 {
    41     if(value->isShared())
    42         value = new StringValue(value->data);
    43 
    44     value->markUnshareable();
    45 
    46     return value->data[index];
    47 }
    48 
    49 String::StringValue::StringValue(const char *initValue)
    50 {
    51     init(initValue);
    52 }
    53 
    54 String::StringValue::StringValue(const StringValue& rhs)
    55 {
    56     init(rhs.data);
    57 }
    58 
    59 String::StringValue::~StringValue()
    60 {
    61     delete [] data;
    62 }
    63 
    64 void String::StringValue::init(const char *value)
    65 {
    66     data = new char[strlen(value) + 1];
    67     strcpy(data, value);
    68 }

    引用计数类rcobject:

     1 //rcobject.h
     2 
     3 class RCObject {
     4 protected:
     5     RCObject();
     6     RCObject(const RCObject &rhs);
     7     RCObject& operator=(const RCObject &rhs);
     8     virtual ~RCObject() = 0;
     9 
    10 public:
    11     void addReference();
    12     void removeReference();
    13     void markUnshareable();
    14     bool isShareable() const;
    15     bool isShared() const;
    16 private:
    17     int refCount;
    18     bool shareable;
    19 };
    20 
    21 
    22 //rcobject.cpp
    23 #include "rcobject.h"
    24 
    25 RCObject::RCObject()
    26     : refCount(0), shareable(true)
    27 {
    28 
    29 }
    30 
    31 RCObject::RCObject(const RCObject &rhs)
    32     :refCount(0), shareable(true)
    33 {
    34 
    35 }
    36 
    37 RCObject& RCObject::operator=(const RCObject &rhs)
    38 {
    39     return *this;
    40 }
    41 
    42 RCObject::~RCObject()
    43 {
    44 
    45 }
    46 
    47 void RCObject::addReference()
    48 {
    49     ++refCount;
    50 }
    51 
    52 void RCObject::removeReference()
    53 {
    54     if(--refCount == 0) delete this;
    55 }
    56 
    57 void RCObject::markUnshareable()
    58 {
    59     shareable = false;
    60 }
    61 
    62 bool RCObject::isShareable() const
    63 {
    64     return shareable;
    65 }
    66 
    67 bool RCObject::isShared() const
    68 {
    69     return refCount > 1;
    70 }

    用来管理rcstring属性的简单智能指针:

     1 //rcptr.h
     2 
     3 template <typename T>
     4 class RCPtr {
     5 public:
     6     RCPtr(T *realPtr = 0);
     7     RCPtr(const RCPtr &rhs);
     8     ~RCPtr();
     9 
    10 public:
    11     RCPtr& operator= (const RCPtr &rhs);
    12     T* operator-> ()const;
    13     T& operator* ()const;
    14 
    15 private:
    16     T *pointee;
    17     void init();
    18 };
    19 
    20 template <typename T>
    21 RCPtr<T>::RCPtr(T *realPtr)
    22     :pointee(realPtr)
    23 {
    24     init();
    25 }
    26 
    27 template <typename T>
    28 RCPtr<T>::RCPtr(const RCPtr& rhs)
    29     :pointee(rhs.pointee)
    30 {
    31     init();
    32 }
    33 
    34 template <typename T>
    35 RCPtr<T>& RCPtr<T>::operator=(const RCPtr& rhs)
    36 {
    37     if(pointee != rhs.pointee) {
    38         if(pointee) pointee->removeReference();
    39 
    40         pointee = rhs.pointee;
    41 
    42         init();
    43     }
    44 
    45     return *this;
    46 }
    47 
    48 template <typename T>
    49 RCPtr<T>::~RCPtr()
    50 {
    51     if(pointee) pointee->removeReference();
    52 }
    53 
    54 template <typename T>
    55 T* RCPtr<T>::operator-> () const 
    56 {
    57     return pointee;
    58 }
    59 
    60 template <typename T>
    61 T& RCPtr<T>::operator* () const
    62 {
    63     return *pointee;
    64 }
    65 
    66 template <typename T>
    67 void RCPtr<T>::init()
    68 {
    69     if(pointee == 0) return;
    70     if(pointee->isShareable() == false)
    71         pointee = new T(*pointee);
    72 
    73     pointee->addReference();
    74 }
  • 相关阅读:
    卡片悬停效果制作
    一个简单的登录页
    登录oracle ORA-12541: TNS:no listener报错
    Tomcat启动超时问题Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds
    获取input type=radio属性的value值
    Mybatic逆向工程的使用
    Mysql下载与安装
    JQuery操作input
    Java集合list,map,set区别及遍历
    List<Map<String, Object>>取值
  • 原文地址:https://www.cnblogs.com/jojodru/p/2861335.html
Copyright © 2020-2023  润新知