当前位置: 首页 > news >正文

实现string类

 

#pragma once#include <cstddef>
#include <cstring>
#include <algorithm>
#include <stdexcept>// namespace M {
class string {
public:static const size_t s_min_capacity;
private:char* data_;        // 字符串数据size_t size_;       // 字符串长度size_t capacity_;   // 容量// 重新分配内存的辅助函数void realloc_data(size_t new_cap) {new_cap = std::max(new_cap, s_min_capacity);char* new_data = new char[new_cap + 1];if (size_ > 0) {std::memcpy(new_data, data_, size_);}new_data[size_] = '\0';delete[] data_;data_ = new_data;capacity_ = new_cap;  // capacity_存储用户数据容量
    }public:// 默认构造函数string() : size_(0), capacity_(s_min_capacity) {data_ = new char[capacity_ + 1];data_[0] = '\0';}// 从C风格字符串构造string(const char* str) {if (!str) {throw std::invalid_argument("null pointer");}size_ = std::strlen(str);capacity_ = std::max(size_, s_min_capacity);data_ = new char[capacity_ + 1];std::memcpy(data_, str, size_ + 1);}// 二进制安全的构造函数string(const void* data, size_t len) {if (!data) {throw std::invalid_argument("null pointer");}size_ = len;capacity_ = std::max(len, s_min_capacity);data_ = new char[capacity_ + 1];std::memcpy(data_, data, len);data_[len] = '\0';}// 拷贝构造函数string(const string& other) : size_(other.size_), capacity_(other.capacity_) {data_ = new char[capacity_ + 1];std::memcpy(data_, other.data_, size_ + 1);}// 移动构造函数string(string&& other) noexcept : data_(other.data_), size_(other.size_), capacity_(other.capacity_) {other.data_ = nullptr;other.size_ = 0;other.capacity_ = 0;}// 析构函数~string() {delete[] data_;}// 拷贝赋值运算符string& operator=(const string& other) {if (this != &other) {char* new_data = new char[other.capacity_ + 1];std::memcpy(new_data, other.data_, other.size_ + 1);delete[] data_;data_ = new_data;size_ = other.size_;capacity_ = other.capacity_;}return *this;}// 移动赋值运算符string& operator=(string&& other) noexcept {if (this != &other) {delete[] data_;data_ = other.data_;size_ = other.size_;capacity_ = other.capacity_;other.data_ = nullptr;other.size_ = 0;other.capacity_ = 0;}return *this;}// 预分配内存void reserve(size_t new_cap) {if (new_cap > capacity_) {realloc_data(new_cap);}}// 释放多余内存void shrink_to_fit() {if (capacity_ > size_) {realloc_data(size_);}}// append 函数string& append(const char* str, size_t len) {if (!str) throw std::invalid_argument("null pointer");if (size_ + len > capacity_) {reserve((size_ + len) * 2);}std::memcpy(data_ + size_, str, len);size_ += len;data_[size_] = '\0';return *this;}string& append(const char* str) {if (!str) throw std::invalid_argument("null pointer");return append(str, std::strlen(str));}// 获取数据const char* c_str() const noexcept { return data_; }const char* data() const noexcept { return data_; }size_t size() const noexcept { return size_; }size_t capacity() const noexcept { return capacity_; }bool empty() const noexcept { return size_ == 0; }
};
// } // namespace M
const size_t string::s_min_capacity = 15;
View Code

 

测试:

#include <cassert>
#include <iostream>
#include <cstring>
#include "string.h"// 用于测试的辅助函数
#define TEST_CASE(name) \do { \std::cout << "Running test case: " << #name << "... "; \test_##name(); \std::cout << "PASSED" << std::endl; \} while (0)// 测试构造函数
void test_constructors() {// 默认构造string s1;assert(s1.empty());assert(s1.size() == 0);assert(s1.capacity() == 15);assert(s1.c_str()[0] == '\0');// C风格字符串构造string s2("hello");assert(s2.size() == 5);assert(s2.capacity() >= 5);assert(strcmp(s2.c_str(), "hello") == 0);// 二进制安全构造char data[] = {'H', 'e', 'l', 'l', 'o', '\0', 'W', 'o', 'r', 'l', 'd'};string s3(data, 11);assert(s3.size() == 11);assert(memcmp(s3.data(), data, 11) == 0);// nullptr 检查try {string s4(nullptr);assert(false);  // 不应该到达这里} catch (const std::invalid_argument&) {// 预期的异常
    }
}// 测试拷贝操作
void test_copy_operations() {string s1("hello");// 拷贝构造string s2(s1);assert(strcmp(s2.c_str(), "hello") == 0);assert(s1.c_str() != s2.c_str());  // 深拷贝检查// 拷贝赋值string s3;s3 = s1;assert(strcmp(s3.c_str(), "hello") == 0);assert(s1.c_str() != s3.c_str());  // 深拷贝检查
}// 测试移动操作
void test_move_operations() {// 移动构造string s1("hello");const char* original_data = s1.c_str();string s2(std::move(s1));assert(s2.c_str() == original_data);  // 数据被移动assert(s1.empty());                   // s1 被清空assert(s1.c_str() == nullptr);       // s1 的指针被置空// 移动赋值string s3;s3 = std::move(s2);assert(s3.c_str() == original_data);  // 数据被移动assert(s2.empty());                   // s2 被清空assert(s2.c_str() == nullptr);       // s2 的指针被置空
}// 测试容量管理
void test_capacity_management() {string s;assert(s.capacity() == 15);  // 初始容量
    s.reserve(20);assert(s.capacity() >= 20);s.append("hello");size_t cap = s.capacity();s.shrink_to_fit();assert(s.capacity() == 15);  // 回到最小容量
}// 测试 append 操作
void test_append_operations() {string s;// 普通appends.append("hello");assert(strcmp(s.c_str(), "hello") == 0);// 触发扩容的appends.append(" world");assert(strcmp(s.c_str(), "hello world") == 0);// 二进制数据appendchar binary[] = {'!', '\0', '!'};s.append(binary, 3);assert(s.size() == 14);assert(memcmp(s.data() + 11, binary, 3) == 0);
}// 测试边界条件
void test_edge_cases() {// 空字符串string s1("");assert(s1.size() == 0);assert(s1.c_str()[0] == '\0');// 大量数据std::string long_str(1000, 'x');string s2(long_str.c_str());assert(s2.size() == 1000);assert(memcmp(s2.data(), long_str.c_str(), 1000) == 0);
}// 测试异常安全性
void test_exception_safety() {// 测试空指针try {string s1(nullptr);assert(false);} catch (const std::invalid_argument&) {}try {string s2;s2.append(nullptr);assert(false);} catch (const std::invalid_argument&) {}
}int main() {TEST_CASE(constructors);TEST_CASE(copy_operations);TEST_CASE(move_operations);TEST_CASE(capacity_management);TEST_CASE(append_operations);TEST_CASE(edge_cases);TEST_CASE(exception_safety);std::cout << "\nAll tests passed!" << std::endl;return 0;
}
View Code

 

http://www.zskr.cn/news/51215.html

相关文章:

  • 2025年甘肃兰州专业的广告物料制作公司推荐
  • OpenAI Agent Kit 全网首发深度解读与上手指南 - 详解
  • supabase
  • 2025年加工型辣椒种子生产厂家排名前十:权威评测与选择攻略
  • 251116
  • 2025年线椒种子品牌前十强排名:专业选购指南与厂家实力解析
  • 华为鲲鹏 Aarch64 环境下多 Oracle 数据库汇聚操作指南 CMP(类 Cloudera CDP 7.3) - 指南
  • 这段时间的NOIP模拟赛
  • 《重生之我成为世界顶级黑客》第三章:艰难的抉择
  • docker - 6 docker 部署 net core
  • 详细介绍:系统同步输出延迟分析(七)
  • 六相电机矢量控制仿真
  • 大一新生记录成为嵌入式工程师的第一天
  • 从Transformer到LLaMA:AI大模型工程化实践完整路径解析
  • 2025送女生礼物推荐全攻略:从心意到实用的精准选择
  • 2025年11月安徽学历提升服务排行情况
  • 2025年口碑好的全自动玩具充棉机厂家推荐及选购指南
  • 2025年比较好的贴片电位器厂家最新权威实力榜
  • 2025年耐用的NXG型滚柱式电机逆止器厂家最新实力排行
  • 25.Python自动化开发-考勤处理
  • 27.Python自动化开发-微信统计
  • 2025年口碑好的切不锈钢圆锯机品牌厂家排行榜
  • 22.Python制作12306查票工具
  • 2025年热门的型钢汽车铰链锯切专机厂家推荐及选择参考
  • Redis:访问redis报错(error) NOAUTH Authentication required
  • 20.Python协程详解公开课
  • 叮咚~
  • 2025年11月国内维修厂家综合实力与口碑推荐排行榜
  • 2025年评价高的光伏逆变器柜机柜空调TOP实力厂家推荐榜
  • 2025年评价高的晶铸石栏杆TOP实力厂家推荐榜