勤能补拙,厚积薄发

合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下
随笔 - 19, 文章 - 0, 评论 - 3, 引用 - 0
数据加载中……

More Effective C++ (item29, part1)

refence counting
引用计数是C++中的常用计数,这里补全了文中的String类,并写了测试代码,已在gcc 4.4.1下编译通过
String.hpp文件内容如下:

 

  1 #include <string.h>
  2 #include <iostream>
  3 class String {
  4     friend bool operator==(const String& lhs, const String& rhs);    
  5     friend std::istream& operator>>(std::istream& inconst String& rhs);
  6     friend std::ostream& operator<<(std::ostream& outconst String& rhs);
  7     public:
  8       String();
  9       String(const char* value = "");
 10       String(const String&);
 11       ~String();
 12       const char& operator[](int index) const;
 13       char& operator[](int index);
 14       String operator=(const String& rhs);
 15       String& operator+=(const String& rhs);
 16     private:
 17       struct StringVal {
 18           char* data;
 19           int refCount;
 20           bool shareable;
 21           StringVal(const char* initValue); 
 22           ~StringVal();
 23       };    
 24       StringVal* value;
 25 };
 26 
 27 String operator+(const String& lhs, const String& rhs);
 28 bool operator==(const String& lhs, const String& rhs);
 29 std::ostream& operator<<(std::ostream& outconst String& rhs);
 30 std::istream& operator>>(std::istream& inconst String& rhs);
 31 
 32 String::StringVal::StringVal(const char* initValue) 
 33 : refCount(1), shareable(true)
 34 {
 35     data = new char[strlen(initValue)+1];
 36     strcpy(data, initValue);
 37 }
 38 
 39 String::StringVal::~StringVal()
 40 {
 41     delete []data;
 42 }
 43 
 44 String::~String()
 45 {
 46     if (--(value->refCount) == 0) {
 47         delete value;
 48     }
 49 }
 50 
 51 String::String(const char* value)
 52 :value(new StringVal(value))
 53 {
 54 }
 55 
 56 String::String(const String& rhs)
 57 {
 58     if (rhs.value->shareable) {
 59         value = rhs.value;
 60         ++(value->refCount);
 61     } else {
 62         value = new StringVal(rhs.value->data);
 63     }
 64 }
 65 
 66 String String::operator=(const String& rhs)
 67 {
 68     if (rhs.value == value) {
 69         return *this;
 70     } 
 71     if (--(value->refCount) == 0) {
 72         delete value;
 73     }
 74     value = rhs.value;
 75     ++(value->refCount);
 76     return *this;
 77 }
 78 
 79 const char& String::operator[](int index) const
 80 {
 81     return value->data[index];
 82 }
 83 
 84 char& String::operator[](int index)
 85 {
 86     if (value->refCount > 1) {
 87         --(value->refCount);
 88         value = new StringVal(value->data);
 89     }
 90     value->shareable = false;
 91     return value->data[index];
 92 }    
 93 
 94 bool operator==(const String& lhs, const String& rhs)
 95 {
 96     return lhs.value == rhs.value;
 97 }
 98 
 99 String operator+(const String& lhs, const String& rhs)
100 {
101     String tmp(lhs);
102     tmp += rhs;
103     return tmp;
104 }
105 
106 String& String::operator+=(const String& rhs)
107 {
108     char *= new char[strlen(value->data) + strlen(rhs.value->data) + 1];
109     strcpy(p, value->data);
110     strcat(p, rhs.value->data);
111     if (--(value->refCount) == 0) {
112         delete value;
113     }
114     this->value = new StringVal(p);
115     return *this;
116 }
117 
118 std::ostream& operator<<(std::ostream& outconst String& rhs)
119 {
120     out << rhs.value->data;
121     return out;
122 }
123 
124 std::istream& operator>>(std::istream& inconst String& rhs)
125 {
126     in >> rhs.value->data;
127     return in;
128 }
129 

 

test.cpp文件内容如下:

#include "String.hpp"

using std::cout;
using std::endl;

int main()
{
    String s1(
"More Effective C++");
    String s2(s1);
    String s3 
= s1;
    
char c = s1[9];
    s1[
3= 'c';
    cout 
<< "s1[9] = "<< c << endl;
    
if (s1 == s3) {
        cout 
<< "s1 == s3" << endl;
    } 
else {
        cout 
<< "s1 has changed, but not s3\n" 
             
<< "s1 = " << s1 << "\n"
             
<< "s3 = " << s3 << endl;
    }
    s2 
+= s1;
    s3 
= s1 + " and " + s2;
    cout 
<< "s2 + s1 = " << s2 << endl;
    cout 
<< "s3 = " << s3 << endl;
    
return 0;
}

 

运行程序的结果如下:


另外书中还提到了写一个基类来作为引用类基础,下篇继续

posted on 2011-12-19 15:28 lee007 阅读(400) 评论(0)  编辑 收藏 引用 所属分类: Programming Study


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理