C++ string现代写法
一、现代写法实现接口
首先是拷贝构造的现代写法的实现:
string_str(const string_str& st)
:str(nullptr)
{
string_str tem(st.str);
swap(this->str, tem.str);
首先先把this->str置空,temp调用构造函数,用st.str初始化this->str这样就形成一个临时对象,通过swap 然后把this->str和tem.str互换,这样两个对象指向的能存空间就互换了,出了作用域tem调用析构函数就释放了。这样就保证拷贝构造函数成功运行。
另一种写法:
string_str& operator=( string_str s) {
swap(this->str, s.str);
return *this;
}
对s传值操作,不传地址,这样对实参构不成影响,通过swap交换所指空间地址。
operator=现代写法
// 对比下和上面的赋值那个实现比较好?
string& operator=(string s)
{
swap(_str, s._str);
return *this;
}
这和拷贝构造另一种写法类似,对s传值操作,不传地址,这样对实参构不成影响,通过swap交换所指空间地址。
另一种实现方式:
/*
string& operator=(const string& s)
{
if(this != &s)
{
string strTmp(s);
swap(_str, strTmp._str);
}
return *this;
}
*/
同样的这和拷贝构造函数第一种实现方式类似。首先先把this->str置空,temp调用构造函数,用st.str初始化this->str这样就形成一个临时对象,通过swap 然后把this->str和tem.str互换,这样两个对象指向的能存空间就互换了,出了作用域tem调用析构函数就释放了。这样就保证拷贝构造函数成功运行。
二、 现代写法其他接口实现
输入输出:
ostream& operator<<( string_str& str, ostream&out) {
for (size_t i = 0; i < _size; i++) {
out >> str[i];
}
return out;
}
istream& operator<<(string_str& str, istream& in) {
str[0] = '';
_size = 0;
char ch;
ch = in.get();
while (ch != ' ' && ch != ''){
str += ch;
ch = in.get();
}
return in;
}
字符串不能通过cout<<endl和cin>>endl输出的,而是通过调用 ostream& operator<<( string_str& str, ostream&out)和 istream&operator<<(string_str& str, istream& in)来操作单个字符来实现字符串的输入输出。
字符串的输出实际上是对字符串中的单个字符挨个遍历打印,
字符串的输入是对字符插入操作,遇到空格或者回车就会结束输入。
istream& getline( string_str& str, istream& in) {
str.clear();
char ch;
ch = in.get();
while ( ch != '') {
str += ch;
ch = in.get();
}
return in;
}
istream& getline( string_str& str, istream& in)
这个函数和operator>>底层基本相同只不过它只遇到换行结束输入。
插入与删除:
void insert(size_t pos, char ch) {
assert(pos >= 0 && pos <= _size);
if (_size >= _capasity) {
size_t num = _capasity == 0 ? 4 : 2 * _capasity;
this->reserve(num);
}
int p = _size-1;
/* for (size_t i = this->_size; i >= pos; i--) {
this->str[i + 1] = this->str[i];
}*/
while (true) {
this->str[p + 1] = this->str[p];
p--;
if (p < (int)pos) {
break;
}
}
this->_size++;
this->str[pos] = ch;
}
void insert(size_t pos,const char* str1) {
assert(pos >= 0 && pos <= _size);
size_t len = strlen(str1);
if (_size + len > _capasity) {
this->reserve(_size + len);
}
int p = _size - 1;
/* for (size_t i = this->_size; i >= pos; i--) {
this->str[i + 1] = this->str[i];
}*/
while (true) {
this->str[p + len] = this->str[p];
p--;
if (p < (int)pos+len) {
break;
}
}
int j = 0;
for (size_t i = pos; i < pos + len; i++) {
str[i] = str1[j++];
}
_size += len;
str[_size] = '';
}
插入字符和字符串函数是函数重载,基本思想都是把pos位置到npos的字符串后移,插入字符只移动一位,而字符串姚移动len位接在在str[pos]插入ch,而字符串循环插入就行。
void erase(size_t pos, int len = -1) {
assert(pos < _size&& pos >= 0);
if (len == -1|| pos + len >= _size) {
str[pos] = '';
_size = pos;
}
else {
/* int num = pos;
while (true) {
str[num] = str[num + len];
num++;
if (num + len == _size) {
break;
}
}
int p = _size - len;
str[p] = '';
_size = p;*/
strcpy(str + pos, str + pos + len);
int p = _size - len;
str[p] = '';
_size -= len;
}
}
ostream& oper
字符串的删除分为两种情况;
1.len为npos或pos+len大于size这样在str[pos]插入就行了。
2.pos+len小于等于size把str + pos + len位置的字符串考到str + pos就可以了,str[pos]插入就OK了。
字符串比较:
int mystring::operator>(const mystring &s){
return strcmp(p,s.p) ;
}
int mystring::operator<(const char*s){
return strcmp(p,s) ;
}
int mystring::operator<(const mystring &s){
return strcmp(p,s.p);
}
int mystring::operator>(const char*s){
return strcmp(p,s);
}
bool mystring::operator!=(const mystring &s){
if(!strcmp(p,s.p)){
return false ;
}
return true ;
}
bool mystring::operator!=(const char * s){
if(p==NULL){
if(len ==0)
return false ;
else{
return true ;
}
}
if(!strcmp(p,s)){
return false ;
}
else{
return true;
}
}
bool mystring::operator==(const mystring&s){
if(strcmp(s.p,p)==0){
return true;
}
else{
return false;
}
}
bool mystring::operator==(const char *s){
if(s==NULL){
if(len == 0){
return true ;
}
else{
return false ;
}
}
if(strcmp(s,p)==0){
return true ;
}
else{
return false ;
}
}