手写std::string: 从零实现一个简单的字符串类
请实现一个简化版的MyString类(类似std::string),包含构造/析构、拷贝构造、拷贝赋值、移动构造、移动赋值、operator[]、operator+=、c_str()、size(),以及operator<<支持。
回答
Yahuda
class MyString {
char* data;
size_t len;
public:
MyString() : data(nullptr), len(0) {}
MyString(const char* s) : len(s ? strlen(s) : 0) {
data = new char[len + 1];
std::copy(s, s + len, data);
data[len] = '\0';
}
// 拷贝构造
MyString(const MyString& other) : len(other.len) {
data = new char[len + 1];
std::copy(other.data, other.data + len + 1, data);
}
// 移动构造
MyString(MyString&& other) noexcept : data(other.data), len(other.len) {
other.data = nullptr;
other.len = 0;
}
// 拷贝赋值(copy-and-swap惯用法,异常安全)
MyString& operator=(MyString other) {
swap(*this, other);
return *this;
}
~MyString() { delete[] data; }
char& operator[](size_t i) { return data[i]; }
const char& operator[](size_t i) const { return data[i]; }
MyString& operator+=(const MyString& rhs) {
auto new_len = len + rhs.len;
auto new_data = new char[new_len + 1];
std::copy(data, data + len, new_data);
std::copy(rhs.data, rhs.data + rhs.len + 1, new_data + len);
delete[] data;
data = new_data;
len = new_len;
return *this;
}
const char* c_str() const { return data ? data : ""; }
size_t size() const { return len; }
friend void swap(MyString& a, MyString& b) noexcept {
using std::swap;
swap(a.data, b.data);
swap(a.len, b.len);
}
friend std::ostream& operator<<(std::ostream& os, const MyString& s) {
return os << s.c_str();
}
};
关键设计:
- copy-and-swap确保强异常安全。
- 移动操作标记noexcept(STL容器优化)。
- SSO(小字符串优化)未实现,真实std::string通常有。