这阵子不怎么忙,闲时把Effective c++,more Effective c++, Exceptional c++,more Exceptional c++在复习了下,根据c++ primer 中提到设计一个string 类型需要的功能,编了一个异常安全的string 类。类基于shared_ptr<char>实现,使用的是vc9的shared_ptr(发现vc9的shared_ptr的reset函数可能有问题,看boost的源码,觉得boost的是没有问题的。大家可以试试。),大家也可以使用boost的shared_ptr。一直都是关注大家的文章,今天终于写下了自己的文章了。咱们博客有不少强人,希望大家提点建议。
1,头文件: myString.h

 myString.h
myString.h
 1
 2 #include <memory>
#include <memory>
 3
 4 using namespace std::tr1;
using namespace std::tr1;
 5
 6 class myString
class myString
 7

 {
{
 8 private:
private:
 9 shared_ptr<char> data_;
 shared_ptr<char> data_;
10
11 public:
public:
12 explicit myString(const char *cstr = 0);
 explicit myString(const char *cstr = 0);
13 myString(const myString &str);
 myString(const myString &str);
14
15 ~myString();
 ~myString();
16
17 myString& operator=(const myString &str);
 myString& operator=(const myString &str);
18 char& operator[](int index);
 char& operator[](int index);
19 myString operator +(const myString &str);
 myString operator +(const myString &str);
20 myString& operator+=(const myString &str);
 myString& operator+=(const myString &str);
21
22 size_t length();
 size_t length();
23 bool empty();
 bool empty();
24 bool equal(const myString &str);
 bool equal(const myString &str);
25 const char* toCstr();
 const char* toCstr();
26
27 private:
private:
28
29 };
};
30
31
2,实现文件:myString.cpp

 myString.cpp
myString.cpp
  1
  2 #include "stdafx.h"
#include "stdafx.h"
  3 #include "myString.h"
#include "myString.h"
  4
  5 #include <cstring>
#include <cstring>
  6 #include <assert.h>
#include <assert.h>
  7
  8 //异常安全的构造函数实现
//异常安全的构造函数实现
  9 myString::myString(const char *cstr)
myString::myString(const char *cstr)
 10 :data_(const_cast<char*>(cstr))
:data_(const_cast<char*>(cstr))
 11

 {
{
 12 
    
 13 }
}
 14
 15 //异常安全的构造函数实现
//异常安全的构造函数实现
 16 myString::myString(const myString &str)
myString::myString(const myString &str)
 17 :data_(str.data_)
:data_(str.data_)
 18

 {
{
 19
 20 }
}
 21
 22 myString::~myString()
myString::~myString()
 23

 {
{
 24
 25 }
}
 26
 27 myString& myString::operator =(const myString &str)
myString& myString::operator =(const myString &str)
 28

 {
{
 29 //if(&str != this)//不能使用str != *this
    //if(&str != this)//不能使用str != *this
 30 if(equal(str))
    if(equal(str))
 31
 
     {
{
 32 myString temp(str);
        myString temp(str);
 33 data_.swap(temp.data_);
        data_.swap(temp.data_);
 34 //从boost源码看出reset就是使用swap实现的,swap使用
        //从boost源码看出reset就是使用swap实现的,swap使用
 35 //std::swap实现。为什么这里使用reset实现有问题而swap
        //std::swap实现。为什么这里使用reset实现有问题而swap
 36 //没有问题?
        //没有问题?
 37 //data_.reset(str.data_.get());
        //data_.reset(str.data_.get());
 38 }
    }
 39
 40 return *this;
    return *this;
 41 }
}
 42
 43 char& myString::operator [](int index)
char& myString::operator [](int index)
 44

 {
{
 45 assert(index > 0);
    assert(index > 0);
 46 assert(data_.get());
    assert(data_.get());
 47 assert((size_t)index < strlen(data_.get()));
    assert((size_t)index < strlen(data_.get()));
 48
 49 return data_.get()[index];
    return data_.get()[index];
 50 }
}
 51
 52 //+ ,+=号可以互相实现,并且效率差不多。
//+ ,+=号可以互相实现,并且效率差不多。
 53 //因此,此处,并不认为+= 比 +效率要高
//因此,此处,并不认为+= 比 +效率要高
 54 //(如果使用+实现+=)
//(如果使用+实现+=)
 55
 56
 57 myString myString::operator +(const myString &str)
myString myString::operator +(const myString &str)
 58

 {
{
 59
 /**//*assert(str.data_.get());
    /**//*assert(str.data_.get());
 60 assert(data_.get());
    assert(data_.get());
 61 size_t olen = strlen(str.data_.get());
    size_t olen = strlen(str.data_.get()); 
 62 size_t slen = strlen(data_.get());
    size_t slen = strlen(data_.get());
 63 myString temp(new char[olen + slen + 1]);
    myString temp(new char[olen + slen + 1]);
 64 memcpy(temp.data_.get(),data_.get(),slen);
    memcpy(temp.data_.get(),data_.get(),slen);
 65 memcpy(temp.data_.get() + slen,str.data_.get(),olen);
    memcpy(temp.data_.get() + slen,str.data_.get(),olen);
 66 temp.data_.get()[olen+slen] = 0;*/
    temp.data_.get()[olen+slen] = 0;*/
 67
 68 myString temp(*this);
    myString temp(*this);
 69 temp += str;
    temp += str;
 70
 71 return temp;
    return temp;
 72 }
}
 73
 74 myString& myString::operator +=(const myString &str)
myString& myString::operator +=(const myString &str)
 75

 {
{
 76 assert(str.data_.get());
    assert(str.data_.get());
 77 assert(data_.get());
    assert(data_.get());
 78
 79 size_t olen = strlen(str.data_.get());
    size_t olen = strlen(str.data_.get()); 
 80 size_t slen = strlen(data_.get());
    size_t slen = strlen(data_.get());
 81
 82 shared_ptr<char> temp(new char[olen + slen + 1]);
    shared_ptr<char> temp(new char[olen + slen + 1]);
 83 memcpy(temp.get(),data_.get(),slen);
    memcpy(temp.get(),data_.get(),slen);
 84 memcpy(temp.get() + slen,str.data_.get(),olen);
    memcpy(temp.get() + slen,str.data_.get(),olen);
 85 temp.get()[olen+slen] = 0;
    temp.get()[olen+slen] = 0;
 86 
    
 87 data_.swap(temp);
    data_.swap(temp);
 88
 89
 /**//*myString temp = operator +(str);
    /**//*myString temp = operator +(str);
 90 data_.swap(temp.data_);*/
    data_.swap(temp.data_);*/
 91
 92 return *this;
    return *this;
 93 }
}
 94
 95 size_t myString::length()
size_t myString::length()
 96

 {
{
 97 assert(data_.get());
    assert(data_.get());
 98 return strlen(data_.get());
    return strlen(data_.get());
 99 }
}
100
101 bool myString::empty()
bool myString::empty()
102

 {
{
103 return (data_.get() == 0);
    return (data_.get() == 0);
104 }
}
105
106 //两个对象相等、同一对象问题,
//两个对象相等、同一对象问题,
107 //值相等,同一地址?
//值相等,同一地址?
108 bool myString::equal(const myString &str)
bool myString::equal(const myString &str)
109

 {
{
110 return (&str == this);
    return (&str == this);
111 //return (data_.get() == str.data_.get());
    //return (data_.get() == str.data_.get());
112 }
}
113
114 const char* myString::toCstr()
const char* myString::toCstr()
115

 {
{
116 return data_.get();
    return data_.get();
117 }
} 
3,测试代码:

 测试代码
测试代码
 1 #include "myString.h"
#include "myString.h"
 2
 3 int _tmain(int argc, _TCHAR* argv[])
int _tmain(int argc, _TCHAR* argv[])
 4

 {
{
 5
 6 myString tt[10];
    myString tt[10];
 7 char *cx = "";
    char *cx = "";
 8 char *cxx = 0;
    char *cxx = 0;
 9
10 //"" != 0
    //"" != 0
11 myString test1("");
    myString test1("");
12 bool bb = test1.empty();
    bool bb = test1.empty();
13 myString test2("adgsdfg");
    myString test2("adgsdfg");
14 myString test3("");
    myString test3("");
15 myString test4(test2);
    myString test4(test2);
16
17 int len;
    int len;
18 len = test1.length();
    len = test1.length();
19 len = test2.length();
    len = test2.length();
20 len = test3.length();
    len = test3.length();
21 len = test4.length();
    len = test4.length();
22
23 bool bempty;
    bool bempty;
24 bempty = test1.empty();
    bempty = test1.empty();
25 bempty = test2.empty();
    bempty = test2.empty();
26 bempty = test3.empty();
    bempty = test3.empty();
27 bempty = test4.empty();
    bempty = test4.empty();
28
29 
    
30 
    
31 const char * cstr;
    const char * cstr;
32 cstr = test1.toCstr();
    cstr = test1.toCstr();
33 cstr = test2.toCstr();
    cstr = test2.toCstr();
34 cstr = test3.toCstr();
    cstr = test3.toCstr();
35 cstr = test4.toCstr();
    cstr = test4.toCstr();
36
37 bool bequal;
    bool bequal;
38 bequal = test1.equal(test2);
    bequal = test1.equal(test2);
39 bequal = test1.equal(test3);
    bequal = test1.equal(test3);
40 bequal = test1.equal(test4);
    bequal = test1.equal(test4);
41
42 myString test5 = test1 + test2;
    myString test5 = test1 + test2;
43
44 test5 = test4 + test2;
    test5 = test4 + test2;
45
46 test5 +=test4;
    test5 +=test4;
47
48
49 char c;
    char c;
50 c = test1[0];
    c = test1[0];
51 c = test2[0];
    c = test2[0];
52 c = test3[0];
    c = test3[0];
53 c = test4[0];
    c = test4[0];
54 }
} 
4,代码打包地址:/Files/Alex-Lee/myString.rar 
	posted on 2009-03-18 09:12 
Alex-Lee 阅读(1848) 
评论(12)  编辑 收藏 引用