用C++实现string类

今天用C++实现了一个string类,包括构造函数、拷贝构造、赋值构造、流输出、移动构造、重载+号, 发现很多细节都没有考虑到,细节都在注释中,贴在这里作为备忘吧。

 

  1 #include <iostream>
  2 #include <cstring>
  3 
  4 using namespace std;
  5 
  6 
  7 class MyString {
  8 public:
  9     MyString();
 10     MyString(const char *str);
 11     MyString(const MyString& s);
 12     ~MyString();
 13     MyString& operator=(const MyString& s);
 14     MyString operator+(const MyString& s); // 返回一个新的临时变量,而不是*this,一开始写错了成MyString&
 15     friend std::ostream& operator<<(std::ostream& os, const MyString& s); // ostream来调用这个函数,因此要做成friend
 16     const char* c_str() const; // 注意要const,避免某些对象是const的需要调用而这个函数不是const的会调用不了
 17     int size() const; // 同上
 18     MyString(MyString&& s); // C++11,需要转移数据,注意s不能是const,因为会修改s
 19 private:
 20     void _cleanup(); // 通用方式
 21     char *_str; //沿用C语言的风格,遇到0最为结束符号
 22     int _size; // _size冗余存储长度
 23 };
 24 
 25 const char* MyString::c_str() const {
 26     return _str;
 27 }
 28 
 29 int MyString::size() const {
 30     return _size;
 31 }
 32 
 33 MyString::MyString(): _str(nullptr), _size(0){
 34 }
 35 
 36 MyString::MyString(const char * str) {
 37     if (str == nullptr) {
 38         _size = 0;
 39         _str = nullptr;
 40         return;
 41     }
 42     _size = strlen(str);
 43     _str = new char[_size+1];
 44     strcpy(_str, str);
 45     _str[_size] = '\0';
 46 }
 47 
 48 MyString::MyString(const MyString& s) {
 49     _size = s._size; // 为啥可以返回s._size?因为在类的成员函数中可以访问同类型实例对象的私有成员变量,参考:https://www.cnblogs.com/dwdxdy/archive/2012/07/17/2595741.html
 50     _str = new char[_size+1];
 51     strcpy(_str, s._str);
 52     _str[_size] = '\0';
 53 }
 54 
 55 std::ostream& operator<<(std::ostream& os, const MyString& s) {
 56     os << s.c_str(); // s_str函数需要const,因为s是const
 57     return os;
 58 }
 59 
 60 void MyString::_cleanup() {
 61     _size = 0;
 62     if (_str) {
 63         delete []_str; // 注意是删除数组,因此要带上[]
 64         _str = nullptr;
 65     }
 66 }
 67 
 68 MyString& MyString::operator=(const MyString& s) {
 69     _cleanup();
 70     _size = s.size(); // size函数需要const,因为s是const的
 71     _str = new char[_size+1];
 72     strcpy(_str, s._str);
 73     _str[_size] = '\0';
 74     return *this;
 75 }
 76 MyString MyString::operator+(const MyString& s) {
 77     MyString newS;
 78     newS._size = _size + s._size;
 79     newS._str = new char[newS._size+1];
 80 
 81     strcpy(newS._str, _str);
 82     strcpy(newS._str+_size, s._str);
 83     newS._str[newS._size] = '\0';
 84     return newS;
 85 }
 86 
 87 MyString::~MyString() {
 88     _cleanup();
 89 }
 90 
 91 MyString::MyString(MyString&& s) {
 92     _cleanup();
 93     _str = s._str;
 94     _size = s._size;
 95     s._str = nullptr;
 96     s._size = 0;
 97 }
 98 
 99 int main() {
100     std::cout << "Hello, World!" << std::endl;
101 
102     MyString s("Hello, World!");
103     MyString ss(s);
104     std::cout << ss << std::endl;
105     ss = ss+s;
106     std::cout << ss << std::endl;
107 
108     MyString sss(std::move(ss)); // move的用法
109     std::cout << "sss:" << sss << " ss:" << ss << std::endl;
110     return 0;
111 }

 

posted on 2024-02-20 12:36  bytesmover  阅读(1)  评论(0编辑  收藏  举报