這陣子不怎么忙,閑時把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
1

2
#include <memory>3

4
using namespace std::tr1;5

6
class myString7


{8
private:9
shared_ptr<char> data_;10

11
public:12
explicit myString(const char *cstr = 0);13
myString(const myString &str);14

15
~myString();16

17
myString& operator=(const myString &str);18
char& operator[](int index);19
myString operator +(const myString &str);20
myString& operator+=(const myString &str);21

22
size_t length();23
bool empty();24
bool equal(const myString &str);25
const char* toCstr();26

27
private:28

29
};30

31

2,實現文件:myString.cpp
1

2
#include "stdafx.h"3
#include "myString.h"4

5
#include <cstring>6
#include <assert.h>7

8
//異常安全的構造函數實現9
myString::myString(const char *cstr)10
:data_(const_cast<char*>(cstr))11


{12
13
}14

15
//異常安全的構造函數實現16
myString::myString(const myString &str)17
:data_(str.data_)18


{19

20
}21

22
myString::~myString()23


{24

25
}26

27
myString& myString::operator =(const myString &str)28


{29
//if(&str != this)//不能使用str != *this30
if(equal(str))31

{32
myString temp(str);33
data_.swap(temp.data_);34
//從boost源碼看出reset就是使用swap實現的,swap使用35
//std::swap實現。為什么這里使用reset實現有問題而swap36
//沒有問題?37
//data_.reset(str.data_.get());38
}39

40
return *this;41
}42

43
char& myString::operator [](int index)44


{45
assert(index > 0);46
assert(data_.get());47
assert((size_t)index < strlen(data_.get()));48

49
return data_.get()[index];50
}51

52
//+ ,+=號可以互相實現,并且效率差不多。53
//因此,此處,并不認為+= 比 +效率要高54
//(如果使用+實現+=)55

56

57
myString myString::operator +(const myString &str)58


{59

/**//*assert(str.data_.get());60
assert(data_.get());61
size_t olen = strlen(str.data_.get()); 62
size_t slen = strlen(data_.get());63
myString temp(new char[olen + slen + 1]);64
memcpy(temp.data_.get(),data_.get(),slen);65
memcpy(temp.data_.get() + slen,str.data_.get(),olen);66
temp.data_.get()[olen+slen] = 0;*/67

68
myString temp(*this);69
temp += str;70

71
return temp;72
}73

74
myString& myString::operator +=(const myString &str)75


{76
assert(str.data_.get());77
assert(data_.get());78

79
size_t olen = strlen(str.data_.get()); 80
size_t slen = strlen(data_.get());81

82
shared_ptr<char> temp(new char[olen + slen + 1]);83
memcpy(temp.get(),data_.get(),slen);84
memcpy(temp.get() + slen,str.data_.get(),olen);85
temp.get()[olen+slen] = 0;86
87
data_.swap(temp);88

89

/**//*myString temp = operator +(str);90
data_.swap(temp.data_);*/91

92
return *this;93
}94

95
size_t myString::length()96


{97
assert(data_.get());98
return strlen(data_.get());99
}100

101
bool myString::empty()102


{103
return (data_.get() == 0);104
}105

106
//兩個對象相等、同一對象問題,107
//值相等,同一地址?108
bool myString::equal(const myString &str)109


{110
return (&str == this);111
//return (data_.get() == str.data_.get());112
}113

114
const char* myString::toCstr()115


{116
return data_.get();117
}
3,測試代碼:
1
#include "myString.h"2

3
int _tmain(int argc, _TCHAR* argv[])4


{5

6
myString tt[10];7
char *cx = "";8
char *cxx = 0;9

10
//"" != 011
myString test1("");12
bool bb = test1.empty();13
myString test2("adgsdfg");14
myString test3("");15
myString test4(test2);16

17
int len;18
len = test1.length();19
len = test2.length();20
len = test3.length();21
len = test4.length();22

23
bool bempty;24
bempty = test1.empty();25
bempty = test2.empty();26
bempty = test3.empty();27
bempty = test4.empty();28

29
30
31
const char * cstr;32
cstr = test1.toCstr();33
cstr = test2.toCstr();34
cstr = test3.toCstr();35
cstr = test4.toCstr();36

37
bool bequal;38
bequal = test1.equal(test2);39
bequal = test1.equal(test3);40
bequal = test1.equal(test4);41

42
myString test5 = test1 + test2;43

44
test5 = test4 + test2;45

46
test5 +=test4;47

48

49
char c;50
c = test1[0];51
c = test2[0];52
c = test3[0];53
c = test4[0];54
}
4,代碼打包地址:/Files/Alex-Lee/myString.rar

