本文实现一个简单的string类,主要实现构造函数和append函数,以及=运算符。
头文件
class string{
public:
string();
string(const string& str);
string(const char* str);
size_t length() const;//字符串长度
const char* c_str() const;// 返回c风格的char的指针
~string();
string& operator=(const string& str);
string& operator=(const char* str);
string& append(const string& str);
string& append(const char* str);
private:
char* p_str;
size_t p_str_len;
};
这里length()函数和c_str()函数需要设置为const函数。
这两个函数需要用于构造函数中,const修饰的变量调用的函数必须是const函数。
构造函数和重载=的思路:
1.先计算出传入字符串的长度len
2.new一个长度为len+1的数组,首地址赋值给p_str
3.遍历传入字符串,依次赋值给p_str
4. 重载=时,要返回当前实例的指针值*this
append函数的思路:
- 先计算出传入字符串的长度len
- 创建一个临时char数组tmp,长度为len+p_str_len;
- 将原来的char数组依次拷贝到tmp中
- 再将传入的字符串,接着上面的下标拷贝到tmp中
- 将原来的char数组delete,建立新的数组,将tmp依次拷贝回这个新数组中
- 设置最后一位’\0’
- 返回*this
实现cpp文件
#include <stdio.h>
#include <malloc.h>
#include "string.h"
string::string():p_str(NULL),p_str_len(0)
{
}
string::string(const string& str)
{
size_t len = str.length();
const char* t_str = str.c_str();
p_str_len = len;
p_str = new char[len+1];//最后一位存放'\0'
for(size_t i=0; i<=len; ++i)
{
p_str[i] = t_str[i];
}
}
string::string(const char* str)
{
if(NULL == str)
{
return;
}
size_t len = 0;
while(str[len] != '\0')//计算char*的长度
{
len++;
}
p_str_len = len;
p_str = new char[len+1];//最后一位存放'\0'
for(size_t i=0; i<=len; ++i)
{
p_str[i] = str[i];
}
}
string::~string()
{
delete[] p_str;
}
size_t string::length() const
{
return p_str_len;
}
const char* string::c_str() const
{
return p_str;
}
string& string::operator=(const string& str)
{
size_t len = str.length();
if(len == 0)
{
return *this;
}
const char* t_str = str.c_str();
p_str_len = len;
p_str = new char[len+1];
for(size_t i=0; i<=len; ++i)
{
p_str[i] = t_str[i];
}
return *this;
}
string& string::operator=(const char* str)
{
if(NULL == str)
{
return *this;
}
p_str_len = 0;
while(str[p_str_len] != '\0')
{
p_str_len++;
}
p_str = new char[p_str_len+1];
for(size_t i = 0; i<=p_str_len; ++i)
{
p_str[i] = str[i];
}
return *this;
}
string& string::append(const string& str)
{
size_t len = str.length();
if(len == 0)
{
return *this;
}
const char* t_str = str.c_str();
size_t new_len = p_str_len + len;//新字符串的总长度
char* tmp = new char[new_len];//设置临时变量,扩大空间
//先拷贝原字符串到临时变量
for(size_t i=0; i<p_str_len; ++i)
{
tmp[i] = p_str[i];
}
//再拷贝传入参数的字符串
for(size_t i=p_str_len; i<new_len; ++i)
{
tmp[i] = t_str[i-p_str_len];
}
delete[] p_str;//删除原来的变量
p_str_len = new_len;
p_str = new char[p_str_len + 1];//重新申请空间
for(size_t i=0; i<p_str_len; ++i)
{
p_str[i] = tmp[i];
}
p_str[p_str_len] = '\0';
delete[] tmp;
return *this;
}
string& string::append(const char* str)
{
if(str == NULL)
{
return *this;
}
int len = 0;
while(str[len] != '\0')//计算str的长度
{
len++;
}
size_t new_len = p_str_len + len;//新字符串的总长度
char* tmp = new char[new_len];//设置临时变量,扩大空间
//先拷贝原字符串到临时变量
for(size_t i=0; i<p_str_len; ++i)
{
tmp[i] = p_str[i];
}
//再拷贝传入参数的字符串
for(size_t i=p_str_len; i<new_len; ++i)
{
tmp[i] = str[i-p_str_len];
}
delete[] p_str;//删除原来的变量
p_str_len = new_len;
p_str = new char[p_str_len + 1];//重新申请空间
for(size_t i=0; i<p_str_len; ++i)
{
p_str[i] = tmp[i];
}
p_str[p_str_len] = '\0';
delete[] tmp;
return *this;
}
注意,这些成员函数不能相互调用,否则delete会出错。
append函数会改变原来的string。
主函数调用:
#include <stdio.h>
#include "string.h"
int main()
{
char s[10] = "abc\0";
string s0(s);
printf("s0:%s\n", s0.c_str());
string s1(s0);
printf("s1:%s\n", s1.c_str());
string s2 = s;
printf("s2:%s\n", s2.c_str());
string s3 = s2;
printf("s3:%s\n", s3.c_str());
string s4 = s1.append(s);
printf("s4:%s\n", s4.c_str());
printf("s1:%s\n", s1.c_str());
string s5 = s1.append(s3).append("123");
printf("s5:%s\n", s5.c_str());
string s6 = "123";
printf("s6:%s\n", s6.c_str());
return 0;
}
输出结果为:
s0:abc
s1:abc
s2:abc
s3:abc
s4:abcabc
s1:abcabc
s5:abcabcabc123
s6:123