// 头文件
#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
class myString
{
friend ostream & operator<<(ostream & out, myString &) ;
friend istream & operator>>(istream & in, myString &) ;
public:
myString(); // 默认构造
virtual ~myString();
myString(const char *); // 由字符串构造
myString(const myString &); // 拷贝构造函数
myString & operator=(const myString &); // 拷贝赋值运算符
myString & operator=(const char *); // 由字符串构造
myString(myString &&) noexcept; // 移动构造函数
myString & operator=(myString &&) noexcept; // 移动赋值运算符
int getLength() const;
int getCapacity() const;
const char * getStr() const; // 获取 C 字符串
char & operator[](int); // 获取 第 i 位字符
bool operator==(const myString& str); // 判断两个字符串是否相等
void append(char c); // 追加一个字符
void append(const char * s); // 追加一个字符串
myString operator+(const char * s); // 拼接字符串
myString operator+(const myString & s2); // 拼接字符串
myString & operator+=(const char * s); // 追加字符串
myString & operator+=(const myString & s); // 追加字符串
protected:
private:
char * str;
int length;
int capacity;
};
#endif // MYSTRING_H
#include "MyString.h"
myString::myString()
{
this->length = 0;
this->capacity = 15;
this->str = (char *)malloc(sizeof(char) * this->capacity);// 默认分配一个长度为15的字符数组,初始化为空串
this->str[0] = '\0';
}
myString::~myString()
{
//dtor
if(this->str != nullptr) {
free(this->str);
}
}
myString::myString(const char * s)
{
if(s != nullptr) {
int sz = strlen(s);
this->length = sz;
this->capacity = sz+1;
this->str = (char * ) malloc(sizeof(char) * this->capacity); // 按字符串大小复制
strcpy(this->str,s);
} else {
this->length = 0;
this->capacity = 15;
this->str = (char *)malloc(sizeof(char) * this->capacity);// 默认分配一个长度为15的字符数组,初始化为空串
this->str[0] = '\0';
}
}
myString::myString(const myString & s)
{
this->length = s.getLength();
this->capacity = s.getCapacity();
this->str = (char * ) malloc(sizeof(char) * this->capacity); // 按字符串大小复制
strcpy(this->str,s.getStr());
}
// 移动构造函数
myString::myString(myString && s) noexcept {
this->length = s.length;
this->capacity = s.capacity;
this->str = s.str;
s.length = 0;
s.capacity = 0;
s.str = nullptr;
}
myString & myString::operator=(myString && s) noexcept {
if(this != & s) { // 是否自赋值
free(this->str);
this->length = s.length;
this->capacity = s.capacity;
this->str = s.str;
s.length = 0;
s.capacity = 0;
s.str = nullptr;
}
return *this;
}
myString & myString::operator=(const myString & s) { // 拷贝赋值运算符
if(this != &s) { // 检查自赋值
int sz = s.getLength();
if(sz < this->capacity) { // 如果原字符串容量够,那么直接拷贝
this->length = sz;
strcpy(this->str,s.getStr());
} else { // 容量不够,释放掉原有内存,重新申请
free(this->str); // 释放掉原有的字符串
this->length = s.getLength();
this->capacity = s.getCapacity();
this->str = (char * ) malloc(sizeof(char) * this->capacity); // 按字符串大小复制
strcpy(this->str,s.getStr());
}
}
return *this;
}
myString & myString::operator=(const char * s) { // 字符串构造
if(s != nullptr) {
int sz = strlen(s);
if(sz < this->capacity) { // 如果原字符串容量够,那么直接拷贝
this->length = sz;
strcpy(this->str,s);
} else { // 容量不够,释放掉原有内存,重新申请
free(this->str);
this->length = sz;
this->capacity = sz+1;
this->str = (char *)malloc(sizeof(char) * this->capacity);
strcpy(this->str,s);
}
} else {
this->length = 0;
this->capacity = 15;
this->str = (char *)malloc(sizeof(char) * this->capacity);// 默认分配一个长度为15的字符数组,初始化为空串
this->str[0] = '\0';
}
return *this;
}
int myString::getLength() const
{
return this->length;
}
int myString::getCapacity() const
{
return this->capacity;
}
const char * myString::getStr() const // 不允许修改 str
{
return this->str;
}
char & myString::operator[](int i)
{
if(i < 0 || i > this->length) {
cout << "index out of range!" << endl;
return this->str[this->length]; // 返回最后一个字符,也就是'\0'
}
return this->str[i];
}
bool myString::operator==(const myString & s)
{
if(this->length != s.getLength()) return false;
return strcmp(this->str,s.getStr()) == 0;
}
void myString::append(char c)
{
int sz = 1 + this->length;
if(sz >= this->capacity) { // 追加后字符大于字符数组长度
while(this->capacity <= (sizeof(char) * sz)) this->capacity = (this->capacity + this->capacity >> 1); // 容量变为1.5,直到大于拼接字符串的长度
char * newStr = (char *)malloc(this->capacity);
strcpy(newStr,this->str);
newStr[sz] = c;
newStr[sz+1] = '\0';
free(this->str);
this->str = newStr;
this->length = sz;
} else {
this->str[sz] = c;
this->str[sz+1] = '\0';
this->length = sz;
}
}
void myString::append(const char * s)
{
int sz = strlen(s) + this->length;
if(sz >= this->capacity) { // 追加后字符串大于字符数组长度
while(this->capacity <= (sizeof(char) * sz)) this->capacity = (this->capacity + this->capacity / 2); // 容量变为1.5,直到大于拼接字符串的长度
char * newStr = (char *)malloc(this->capacity);
strcpy(newStr,this->str);
newStr = strcat(newStr,s);
free(this->str);
this->str = newStr;
this->length = sz;
} else {
this->str = strcat(this->str, s);
this->length = sz;
}
}
myString myString::operator+(const char * s) // 拼接字符串
{
myString res(this->str);
res += s;
return res;
}
myString myString::operator+(const myString & s) // 拼接字符串
{
this->append(s.getStr());
return *this;
}
myString & myString::operator+=(const char * s) // 追加字符串
{
this->append(s);
return *this;
}
myString & myString::operator+=(const myString & s) // 追加字符串
{
this->append(s.getStr());
return *this;
}
ostream & operator<<(ostream & out, myString & myStr)
{
out << (myStr.str) ;
return out;
}
istream & operator>>(istream & in, myString & myStr)
{
in >> myStr.str;
return in;
}
#include <iostream>
#include "myString.h"
using namespace std;
int main()
{
myString str1("hello world!");
cout << str1.getLength() << endl;
cout << str1.getCapacity() << endl;
cout << str1 << endl;
str1.append(" I am Chinese!");
cout << str1.getLength() << endl;
cout << str1.getCapacity() << endl;
cout << str1 << endl;
str1.append(" 2021!");
cout << str1.getLength() << endl;
cout << str1.getCapacity() << endl;
cout << str1 << endl;
myString str2;
str2 += "I am a dog.";
cout << str2.getLength() << endl;
cout << str2.getCapacity() << endl;
cout << str2 << endl;
cout << (str1 == str2) << endl;
myString str3(str2);
str3 += str1;
cout << str3.getLength() << endl;
cout << str3.getCapacity() << endl;
cout << str3 << endl;
myString str4 = str2 + str3;
cout << str4.getLength() << endl;
cout << str4.getCapacity() << endl;
cout << str4 << endl;
myString str5 = str2 + " 2021 next travel!";
cout << str5.getLength() << endl;
cout << str5.getCapacity() << endl;
cout << str5 << endl;
str5[10] = 'a';
str5[8] = 'h';
str5[16] = 'l';
cout << str5.getLength() << endl;
cout << str5.getCapacity() << endl;
cout << str5 << endl;
cout << endl;
str5 = std::move(str5);
cout << str5.getLength() << endl;
cout << str5.getCapacity() << endl;
cout << str5 << endl;
cout << endl;
myString str6 = std::move(str5);
cout << str5.getLength() << endl;
cout << str5.getCapacity() << endl;
cout << str5 << endl;
cout << str6.getLength() << endl;
cout << str6.getCapacity() << endl;
cout << str6 << endl;
return 0;
}