1.MyString 分文件实现
一、分文件核心规则
.h 头文件:只写声明(类、函数、变量),加头文件保护,禁止写实现、禁止using namespace std。.cpp 源文件:只写实现,包含头文件,成员函数加类名::,静态成员在此定义。
声明与实现函数签名必须完全一致(参数、const、返回值)。
二、内存管理(重中之重)
必须实现深拷贝三大件:拷贝构造、赋值重载、析构函数,杜绝浅拷贝崩溃。
赋值重载用拷贝交换法,简洁安全。
扩容用reserve,默认2 倍扩容,减少内存分配。
字符串始终以\0结尾。
三、函数实现要点
const函数:不修改对象的接口必须加const。
默认参数:仅在头文件声明中写。
迭代器:用原生指针实现,区分普通 /const 版本。
运算符:+=做成员函数,+/==/<<做全局函数。
四、高频避坑
越界访问:用assert校验下标。
头文件缺失:strlen→<cstring>,isspace→<cctype>。
内存匹配:new\[\]必须搭配delete\[\]。
编译:所有.cpp文件必须一起编译链接
2.程序实现
1.h文件
cpp
#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
#include <cstring>
#include <cassert>
#include <algorithm>
// 头文件严禁写 using namespace std!!!
class MyString
{
public:
typedef char* iterator;
typedef const char* const_iterator;
// 静态常量声明
const static std::size_t npos;
// 构造/析构/拷贝
MyString();
MyString(const char* s);
MyString(const MyString& s);
MyString& operator=(MyString s);
~MyString();
void Swap(MyString& s);
// 迭代器
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
// 容量
std::size_t size() const;
std::size_t capacity() const;
bool empty() const;
void clear();
void reserve(std::size_t n);
void resize(std::size_t n, char ch = '\0');
// 访问
char& operator[](std::size_t pos);
const char& operator[](std::size_t pos) const;
const char* c_str() const;
// 修改
void push_back(char ch);
void append(const char* s);
MyString& operator+=(char ch);
MyString& operator+=(const char* s);
MyString& operator+=(const MyString& s);
void insert(std::size_t pos, char ch);
void erase(std::size_t pos, std::size_t len = npos);
// 查找
std::size_t find(char ch, std::size_t pos = 0) const;
std::size_t find(const char* s, std::size_t pos = 0) const;
private:
char* _str;
std::size_t _size;
std::size_t _capacity;
};
// 全局运算符声明
MyString operator+(const MyString& s1, const MyString& s2);
bool operator==(const MyString& s1, const MyString& s2);
bool operator!=(const MyString& s1, const MyString& s2);
bool operator<(const MyString& s1, const MyString& s2);
std::ostream& operator<<(std::ostream& out, const MyString& s);
std::istream& operator>>(std::istream& in, MyString& s);
#endif
2.cpp文件
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include "MyString.h"
#include <cctype> // 修复:isspace() 必须包含的头文件!
using namespace std;
// 静态常量定义
const size_t MyString::npos = -1;
// 构造/析构
MyString::MyString()
: _str(new char[1] {'\0'})
, _size(0)
, _capacity(0)
{
}
MyString::MyString(const char* s)
{
_size = strlen(s);
_capacity = _size;
_str = new char[_capacity + 1];
strcpy(_str, s);
}
MyString::MyString(const MyString& s)
{
_size = s._size;
_capacity = s._capacity;
_str = new char[_capacity + 1];
strcpy(_str, s._str);
}
MyString& MyString::operator=(MyString s)
{
Swap(s);
return *this;
}
MyString::~MyString()
{
delete[] _str;
_str = nullptr;
_size = _capacity = 0;
}
void MyString::Swap(MyString& s)
{
swap(_str, s._str);
swap(_size, s._size);
swap(_capacity, s._capacity);
}
// 迭代器
MyString::iterator MyString::begin() { return _str; }
MyString::iterator MyString::end() { return _str + _size; }
MyString::const_iterator MyString::begin() const { return _str; }
MyString::const_iterator MyString::end() const { return _str + _size; }
// 容量
size_t MyString::size() const { return _size; }
size_t MyString::capacity() const { return _capacity; }
bool MyString::empty() const { return _size == 0; }
void MyString::clear()
{
_size = 0;
_str[0] = '\0';
}
void MyString::reserve(size_t n)
{
if (n > _capacity)
{
char* tmp = new char[n + 1];
strcpy(tmp, _str);
delete[] _str;
_str = tmp;
_capacity = n;
}
}
void MyString::resize(size_t n, char ch)
{
if (n <= _size)
{
_size = n;
_str[_size] = '\0';
}
else
{
reserve(n);
for (size_t i = _size; i < n; ++i)
_str[i] = ch;
_size = n;
_str[_size] = '\0';
}
}
// 元素访问
char& MyString::operator[](size_t pos)
{
assert(pos < _size);
return _str[pos];
}
const char& MyString::operator[](size_t pos) const
{
assert(pos < _size);
return _str[pos];
}
const char* MyString::c_str() const { return _str; }
// 修改操作
void MyString::push_back(char ch)
{
if (_size == _capacity)
reserve(_capacity == 0 ? 4 : _capacity * 2);
_str[_size++] = ch;
_str[_size] = '\0';
}
void MyString::append(const char* s)
{
size_t len = strlen(s);
if (_size + len > _capacity)
reserve(_size + len);
strcpy(_str + _size, s);
_size += len;
}
MyString& MyString::operator+=(char ch) { push_back(ch); return *this; }
MyString& MyString::operator+=(const char* s) { append(s); return *this; }
MyString& MyString::operator+=(const MyString& s) { append(s._str); return *this; }
void MyString::insert(size_t pos, char ch)
{
assert(pos <= _size);
if (_size == _capacity)
reserve(_capacity == 0 ? 4 : _capacity * 2);
for (size_t i = _size; i > pos; --i)
_str[i] = _str[i - 1];
_str[pos] = ch;
_size++;
_str[_size] = '\0';
}
void MyString::erase(size_t pos, size_t len)
{
assert(pos < _size);
if (len == npos || pos + len >= _size)
{
_str[pos] = '\0';
_size = pos;
}
else
{
strcpy(_str + pos, _str + pos + len);
_size -= len;
}
}
// 查找
size_t MyString::find(char ch, size_t pos) const
{
assert(pos <= _size);
for (size_t i = pos; i < _size; ++i)
if (_str[i] == ch) return i;
return npos;
}
size_t MyString::find(const char* s, size_t pos) const
{
assert(pos <= _size);
const char* p = strstr(_str + pos, s);
return p ? p - _str : npos;
}
// 全局运算符实现
MyString operator+(const MyString& s1, const MyString& s2)
{
MyString tmp = s1;
tmp += s2;
return tmp;
}
bool operator==(const MyString& s1, const MyString& s2)
{
return strcmp(s1.c_str(), s2.c_str()) == 0;
}
bool operator!=(const MyString& s1, const MyString& s2)
{
return !(s1 == s2);
}
bool operator<(const MyString& s1, const MyString& s2)
{
return strcmp(s1.c_str(), s2.c_str()) < 0;
}
ostream& operator<<(ostream& out, const MyString& s)
{
for (size_t i = 0; i < s.size(); ++i)
out << s[i];
return out;
}
istream& operator>>(istream& in, MyString& s)
{
s.clear();
char ch;
while (in.get(ch) && !isspace(ch))
s += ch;
return in;
}
3.mian文件
cpp
#include "MyString.h"
using namespace std;
int main()
{
MyString s1;
MyString s2("hello world");
MyString s3 = s2;
MyString s4 = s2;
cout << "s1: " << s1 << endl;
cout << "s2: " << s2 << endl;
cout << "s3: " << s3 << endl;
s2[0] = 'H';
s2 += "!!!";
cout << "\n修改后s2: " << s2 << endl;
s2.insert(5, ' ');
s2.erase(5, 1);
cout << "插入删除后: " << s2 << endl;
size_t pos = s2.find('w');
if (pos != MyString::npos)
cout << "字符w位置: " << pos << endl;
return 0;
}
谢谢