文件String.h

#ifndef _STRING_H
#define _STRING_H
class String
{
public:
    String(
const char* cszStr = "");
    String(
const String& rhs);
    String
& operator=(const String& rhs);
    
~String();

    
const char* c_str()const{return value->data;}

public:
    
char& operator[](size_t idx);
    
const char& operator[](size_t idx)const;


public:
    
struct StringValue
    
{
        size_t refCount;
        size_t len;
        
char* data;
    
        StringValue(
const char* cszStr);
        
~StringValue();
    }
;
private:
    StringValue
* value;
}
;
#endif
文件String.cpp:
#include "String.h"
#include 
<string.h>
#include 
<assert.h>

String::String(
const char* cszStr)
{
    value 
= new StringValue(cszStr);
}


String::String(
const String& rhs)
{
    value 
= rhs.value;
    value
->refCount++;
}


String
& String::operator=(const String& rhs)
{
    
if( rhs.value == this->value )return *this;

    
--value->refCount;
    
if( value->refCount == 0 )delete value;
    
    value
->data = rhs.value->data;
    
++value->refCount;
    
return *this;
}


String::
~String()
{
    
if--value->refCount == 0 )delete value;
}


char& String::operator[](size_t idx)
{
    assert( idx 
< value->len && idx >= 0);
    
//if we are sharing value with other String Objects,
    
//break off a separate copy of value for ourselves
    if( value->refCount > 1 )
    
{
        value
->refCount--;
        value 
= new StringValue(value->data);
    }

    
return value->data[idx];
}


const char& String::operator[](size_t idx)const
{
    assert( idx 
< value->len && idx >= 0);
    
return value->data[idx];
}


String::StringValue::StringValue(
const char* cszStr)
    :refCount(
1)
{
    len 
= strlen(cszStr);
    data 
= new char[len + 1];
    strcpy(data, cszStr);
}


String::StringValue::
~StringValue()
{
    delete[] data;
    data 
= 0;
}



 

1、关于成员函数operator[]的备注

Unfortunately, there is no way for C++ compilers to tell us whether a particular use of operator[] is for a read or a write, so we must be pessimistic and assume that all calls to the non-const operator[] are for writes.

不幸的是,C++编译器没有办法告诉我们一个特定的operator[]是用作读的还是写的,所以我们必须保守地假设所有调用非const operator[]的行为都是为了写操作。

 

2、这个版本未能解决的问题

只有一个挥之不去的问题。看一下这样的代码:

String s1 = "Hello";

char *p = &s1[1];

 

现在看增加一条语句:

String s2 = s1;

String的拷贝构造函数使得s2共享s1StringValue对象,

下面这样的语句将有不受欢迎的结果:

*p = 'x';                     // modifies both s1 and s2!

String的拷贝构造函数没有办法检测这样的问题,因为它不知道指向s1拥有的StringValue对象的指针的存在,这样就导致了s1s2同时被修改了。

并且,这个问题不局限于指针:它同样存在于有人保存了一个String的非const operator[]的返回值的引用的情况下。



posted on 2010-07-10 10:32 mildcat 阅读(92) 评论(0)  编辑 收藏 引用 所属分类: C++

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