String类型
以后处理字符串可以直接用String类型 #include
编程能力强不强=处理字符串的能力强不强
C++中的string是一个标准库类型,表示可变长的字符序列,而由于是标准库类型,所以string定义在命名空间std中
ps:
1.得到字符串长度 str2.length()
2.底层是动态的 所以定义指针好
3.字符串哲学系都可能用完释放 所以要提供右值
4.常对象调不了普通方法,所以只读不写都定义为常方法
自写C++标准库中的String类型
class CMyString
{
public:
CMyString(const char*p = nullptr)
//本来是一个有参数的,无参数的 我们写一个带默认值的就可以无参数有参数结合在一起
//无参数的时候p = nullptr 有参数的时候就是用我传入的p
{
if (p != nullptr)
{
// 1.根据p指向得字符串得长度,开辟一块内存空间
mptr = new char[strlen(p) + 1];
// 2.把p指向得字符串拷贝到这块空间上来
strcpy(mptr, p);
}
else
{
//若p传进来是空的,则mptr开辟的空间也为空,所有自构造的时候就要保证:不管传进来的指针是否为空 都能构造出一个string底层空间不为空
mptr = new char[1];
*mptr = 0; // '\0'
}
}
~CMyString()
{
delete []mptr;
mptr = nullptr;
}
CMyString(const CMyString &str)
{
mptr = new char[strlen(str.mptr) + 1];
//最好不要写成 mptr = new char[str.length() + 1];因为接口之间不要有依赖性,不然length函数删了就要改好多
strcpy(mptr, str.mptr);
}
CMyString(CMyString &&str)
{
mptr = str.mptr;
str.mptr = nullptr;
}
// str1 = str2.operator=(str3);
CMyString& operator=(const CMyString &str)
{
if (this == &str)
return *this;
delete[]mptr;
mptr = new char[strlen(str.mptr) + 1];
strcpy(mptr, str.mptr);
return *this;
}
CMyString& operator=(CMyString &&str)
{
if (this == &str)
return *this;
delete[]mptr;
mptr = str.mptr;
str.mptr = nullptr;
return *this;
}
bool operator>(const CMyString &str)const
{
return strcmp(mptr, str.mptr) > 0;
}
bool operator<(const CMyString &str)const
{
return strcmp(mptr, str.mptr) < 0;
//strcmp是从两个字符串的第一个字母开始比较 看哪个在前面
}
bool operator==(const CMyString &str)const
{
return strcmp(mptr, str.mptr) == 0;
}
int length()const {
return strlen(mptr); }
char& operator[](int index) {
return mptr[index]; }
//要加& 返回地址,既能读又能写,不然的话只能看到那个值 不能改
//char是<4 由寄存器返回,那是个立即数,不可写只可读
const char* c_str()const {
return mptr; }
//这个就是只能读 是个常方法
private:
char *mptr;
friend ostream& operator<<(ostream &out, const CMyString &str);
friend CMyString operator+(const CMyString &l, const CMyString &r);
};
CMyString operator+(const CMyString &l, const CMyString &r)
{
int length = l.length() + r.length();
char* p = new char[length + 1];
strcpy(p, l.mptr);
strcat(p, r.mptr);
String tmp(p);
delete []p;
return tmp;
/*
//不能直接返回构造的这个 因为从始至终没有析构过他 会造成内存泄露所以要写成上面那样 原因在于用指针p指向的内存构造了一个临时对象: CMyString(const char*p = nullptr) 但是这个函数结束了p一直没有被析构掉 所以不能这样做
注意之前用int类型的值构造临时对象返回就不会出现这样的烦恼
但是这样做的效率非常低!!!
return String(p);
//不能直接这样 因为1里面根本没有充足的空间去接受
strcat(1.mptr, r.mptr);
*/
}
// CMyString str1 = str2 + str3;
// CMyString str1; str1= str2 + str3;
//访问的是私有成员 所以要声明为友元函数
ostream& operator<<(ostream &out, const CMyString &str)
{
out << str.mptr;
return out;
}
istream& operator>>