随笔 - 20  文章 - 0  评论 - 12  阅读 - 15565

用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   bytesmover  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示