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

C++11中智能指针以及标准模板库 My_string My_stack

在这里插入图片描述
My_string.h

#ifndef MY_STRING_H
#define MY_STRING_H

#include <iostream>
#include <cstring>
#include <stdexcept>

using namespace std;

template<typename T>
class My_string {
private:
    T *ptr;         // 指向字符数组的指针
    int size;       // 字符串的最大容量
    int len;        // 字符串当前长度

public:
    My_string();  // 无参构造
    My_string(const T* src);  // 有参构造
    My_string(int num, T value);  // 重复构造
    My_string(const My_string &other);  // 拷贝构造
    My_string &operator=(const My_string &other);  // 拷贝赋值
    ~My_string();  // 析构函数

    void show() const;  // 显示内容
    void isempty() const;  // 判空
    void isfull() const;  // 判满
    void push_back(T value);  // 尾插
    void pop_back();  // 尾删
    T &at(int index);  // at函数实现
    void clear();  // 清空函数
    T* data();  // 返回C风格字符串
    int get_length() const;  // 返回实际长度
    int get_size() const;  // 返回当前最大容量
    void resize();  // 二倍扩容
    My_string operator+(const My_string &R) const;  // 自定义运算符重载 +
    T operator[](int n) const;  // 自定义运算符重载 []

    // 重载比较运算符
    bool operator>(const My_string &R) const;
    bool operator<(const My_string &R) const;
    bool operator<=(const My_string &R) const;
    bool operator>=(const My_string &R) const;
    bool operator==(const My_string &R) const;
    bool operator!=(const My_string &R) const;

    // 重载 += 运算符
    My_string& operator+=(const My_string &R);

    // 重载输出运算符 <<
    friend ostream& operator<<(ostream &L, const My_string &R) {
        L << R.ptr;
        return L;
    }
};

#include "My_string.cpp"  // 包含实现文件

#endif // MY_STRING_H

My_string.cpp

#include "My_string.h"

// 无参构造
template<typename T>
My_string<T>::My_string() : size(20), len(0) {
    cout << "****************无参构造***********" << endl;
    ptr = new T[size];
    ptr[0] = '\0';  // 表示串为空串
}

// 有参构造
template<typename T>
My_string<T>::My_string(const T* src) {
    cout << "****************一个参数有参构造***********" << endl;
    len = strlen(src);
    size = len + 1;
    ptr = new T[size];
    strcpy(ptr, src);
}

// 初始化字符重复构造
template<typename T>
My_string<T>::My_string(int num, T value) {
    cout << "****************两个参数有参构造***********" << endl;
    len = num;
    size = len + 1;
    ptr = new T[size];
    for (int i = 0; i < num; i++) {
        ptr[i] = value;
    }
    ptr[num] = '\0';
}

// 拷贝构造
template<typename T>
My_string<T>::My_string(const My_string &other) {
    cout << "****************拷贝构造***********" << endl;
    len = other.len;
    size = other.size;
    ptr = new T[size];
    strcpy(ptr, other.ptr);
}

// 拷贝赋值
template<typename T>
My_string<T>& My_string<T>::operator=(const My_string &other) {
    cout << "****************拷贝赋值***********" << endl;
    if (this == &other) {
        return *this;  // 直接返回当前对象
    }
    delete[] ptr;
    len = other.len;
    size = other.size;
    ptr = new T[size];
    strcpy(ptr, other.ptr);
    return *this;
}

// 析构函数
template<typename T>
My_string<T>::~My_string() {
    cout << "****************析构函数***********" << endl;
    delete[] ptr;
}

// 显示内容
template<typename T>
void My_string<T>::show() const {
    cout << "内容: " << ptr << ", 长度: " << len << ", 容量: " << size << endl;
}

// 判空
template<typename T>
void My_string<T>::isempty() const {
    if (len == 0) {
        cout << "字符串为空" << endl;
    }
}

// 判满
template<typename T>
void My_string<T>::isfull() const {
    if (len >= size) {
        cout << "字符串满" << endl;
        resize();
        cout << "重新分配空间" << endl;
    } else {
        cout << "字符串未满" << endl;
    }
}

// 尾插
template<typename T>
void My_string<T>::push_back(T value) {
    isfull();
    ptr[len] = value;
    len++;
    ptr[len] = '\0';
}

// 尾删
template<typename T>
void My_string<T>::pop_back() {
    if (len > 0) {
        len--;
        ptr[len] = '\0';
    }
}

// at函数实现
template<typename T>
T& My_string<T>::at(int index) {
    if (index < 0 || index >= len) {
        throw out_of_range("Index out of range");
    }
    return ptr[index];
}

// 清空函数
template<typename T>
void My_string<T>::clear() {
    ptr[0] = '\0';
    len = 0;
}

// 返回C风格字符串
template<typename T>
T* My_string<T>::data() {
    return ptr;
}

// 返回实际长度
template<typename T>
int My_string<T>::get_length() const {
    return len;
}

// 返回当前最大容量
template<typename T>
int My_string<T>::get_size() const {
    return size;
}

// 君子函数:二倍扩容
template<typename T>
void My_string<T>::resize() {
    size *= 2;
    T* new_ptr = new T[size];
    strcpy(new_ptr, ptr);
    delete[] ptr;
    ptr = new_ptr;
}

// 自定义运算符重载 +
template<typename T>
My_string<T> My_string<T>::operator+(const My_string &R) const {
    My_string temp;
    while (this->len + R.len > temp.size) {
        temp.resize();
    }
    strcpy(temp.ptr, this->ptr);
    strcat(temp.ptr, R.ptr);
    temp.len = this->len + R.len;
    return temp;
}

// 自定义运算符重载 []
template<typename T>
T My_string<T>::operator[](int n) const {
    return ptr[n];
}

// 重载大于运算符
template<typename T>
bool My_string<T>::operator>(const My_string &R) const {
    return strcmp(this->ptr, R.ptr) > 0;
}

// 重载小于运算符
template<typename T>
bool My_string<T>::operator<(const My_string &R) const {
    return strcmp(this->ptr, R.ptr) < 0;
}

// 重载小于等于运算符
template<typename T>
bool My_string<T>::operator<=(const My_string &R) const {
    return strcmp(this->ptr, R.ptr) <= 0;
}

// 重载大于等于运算符
template<typename T>
bool My_string<T>::operator>=(const My_string &R) const {
    return strcmp(this->ptr, R.ptr) >= 0;
}

// 重载相等运算符
template<typename T>
bool My_string<T>::operator==(const My_string &R) const {
    return strcmp(this->ptr, R.ptr) == 0;
}

// 重载不等运算符
template<typename T>
bool My_string<T>::operator!=(const My_string &R) const {
    return strcmp(this->ptr, R.ptr) != 0;
}

// 重载 += 运算符
template<typename T>
My_string<T>& My_string<T>::operator+=(const My_string &R) {
    while (this->len + R.len >= this->size) {
        this->resize();
    }
    strcat(this->ptr, R.ptr);
    this->len += R.len;
    return *this;
}

main.cpp

#include "My_string.h"

int main() {
    My_string<char> str1("Hello");
    My_string<char> str2(" World");

    My_string<char> str3 = str1 + str2;
    str3.show();  

    return 0;
}

栈的模板类

My_stack.h

#ifndef MY_STACK_H
#define MY_STACK_H

#include <iostream>
using namespace std;

template<typename T>
class My_Stack {
private:
    T* ptr;         // 动态数组用于存储栈元素
    int top;        // 栈顶索引
    int capacity;   // 当前容量

    void resize();  // 调整栈的大小

public:
    My_Stack();                // 构造函数
    My_Stack(const My_Stack& other);  // 拷贝构造函数
    ~My_Stack();               // 析构函数

    void push(T value);        // 入栈操作
    T pop();                   // 出栈操作
    T peek();                  // 获取栈顶元素
    bool isEmpty();            // 判断栈是否为空
    int size();                // 获取栈的当前大小
    void swap_t(My_Stack& other); // 交换栈
    void show();               // 显示栈中的内容

    My_Stack& operator=(const My_Stack& other);  // 赋值操作符重载
};

#include "My_stack.cpp"  // 引入实现文件

#endif // MY_STACK_H

My_stack.cpp

#include "My_stack.h"

// 构造函数
template<typename T>
My_Stack<T>::My_Stack() : top(-1), capacity(1) {
    ptr = new T[capacity];  // 初始化容量为1
}

// 拷贝构造函数
template<typename T>
My_Stack<T>::My_Stack(const My_Stack& other) : top(other.top), capacity(other.capacity) {
    ptr = new T[capacity];  // 分配新的内存
    for (int i = 0; i <= top; ++i) {
        ptr[i] = other.ptr[i];  // 深拷贝
    }
}

// 析构函数
template<typename T>
My_Stack<T>::~My_Stack() {
    delete[] ptr;  // 释放动态数组的内存
}

// 动态扩容
template<typename T>
void My_Stack<T>::resize() {
    capacity *= 2;  // 容量翻倍
    T* new_arr = new T[capacity];  // 创建新的数组
    for (int i = 0; i <= top; ++i) {
        new_arr[i] = ptr[i];  // 拷贝原数组元素
    }
    delete[] ptr;  // 释放旧数组
    ptr = new_arr;  // 更新指针
}

// 入栈操作
template<typename T>
void My_Stack<T>::push(T value) {
    if (top >= capacity - 1) {
        resize();  // 容量不足时进行扩容
    }
    ptr[++top] = value;  // 增加栈顶并赋值
    cout << "入栈: " << value << endl;
}

// 出栈操作
template<typename T>
T My_Stack<T>::pop() {
    if (isEmpty()) {
        cout << "栈为空!无法出栈。" << endl;
        return T();  // 返回默认值
    }
    T popValue = ptr[top--];  // 返回栈顶值并减少栈顶索引
    cout << "出栈: " << popValue << endl;
    return popValue;
}

// 获取栈顶元素
template<typename T>
T My_Stack<T>::peek() {
    if (isEmpty()) {
        cout << "栈为空!无法查看栈顶元素。" << endl;
        return T();  // 返回默认值
    }
    return ptr[top];  // 返回栈顶值
}

// 判断栈是否为空
template<typename T>
bool My_Stack<T>::isEmpty() {
    return top == -1;  // 栈为空时,栈顶索引为 -1
}

// 获取栈的当前大小
template<typename T>
int My_Stack<T>::size() {
    return top + 1;  // 返回栈中元素的个数
}

// 交换栈
template<typename T>
void My_Stack<T>::swap_t(My_Stack& other) {
    swap(top, other.top);
    swap(capacity, other.capacity);
    swap(ptr, other.ptr);  // 交换指针
}

// 显示栈中的内容
template<typename T>
void My_Stack<T>::show() {
    if (isEmpty()) {
        cout << "栈为空!" << endl;
        return;
    }

    cout << "栈中的元素: ";
    for (int i = 0; i <= top; ++i) {
        cout << ptr[i] << " ";  // 打印每个元素
    }
    cout << endl;
}

// 赋值操作符重载
template<typename T>
My_Stack<T>& My_Stack<T>::operator=(const My_Stack& other) {
    if (this != &other) {  // 自我赋值检查
        delete[] ptr;  // 释放旧数组
        top = other.top;
        capacity = other.capacity;
        ptr = new T[capacity];  // 分配新的内存
        for (int i = 0; i <= top; ++i) {
            ptr[i] = other.arr[i];  // 深拷贝
        }
    }
    return *this;  // 返回当前对象的引用
}

main.cpp

#include "My_stack.h"

int main() {
    // 创建第一个栈并进行入栈操作
        My_Stack<int> s1;
        s1.push(10);
        s1.push(20);
        s1.push(30);

        // 创建第二个栈并进行入栈操作
        My_Stack<int> s2;
        s2.push(40);
        s2.push(50);

        My_Stack<int> s3 = s2;

        cout<<"s3:";
        s3.show();

        cout <<"交换前:"<< endl;
        cout<<"s1:";
        s1.show();
        cout<<"s2:";
        s2.show();

        // 交换s1和s2的内容
        s1.swap_t(s2);
        cout << "交换后:" << endl;

        cout<<"s1:";
        s1.show();
        cout<<"s2:";
        s2.show();

        // 出栈
        cout<<"从 s1 弹出元素: "<<s1.pop()<<endl;
        cout<<"从 s2 弹出元素: "<<s2.pop()<<endl;

        // 检查栈的大小
        cout<<"s1 当前大小: "<<s1.size()<<endl;
        cout<<"s2 当前大小: "<<s2.size()<<endl;

        // 再次弹出元素
        s1.pop();
        s2.pop();

        cout << "交换后再次弹出后的大小:" << endl;
        cout << "s1 当前大小: " << s1.size() << endl;
        cout << "s2 当前大小: " << s2.size() << endl;


    return 0;
}


http://www.kler.cn/a/327025.html

相关文章:

  • 商品信息的修改、删除功能
  • git commit应遵循的提交规范
  • 一个由Deno和React驱动的静态网站生成器
  • Linux curl命令下载显示时间/速度/大小
  • 前端的导入导出「CommonJS」「ES Module」模块化规范
  • 分布式集群本地缓存
  • Zabbix 7.0 图表中文乱码问题处理步骤
  • 后台数据管理系统 - 项目架构设计-Vue3+axios+Element-plus(0926)
  • leetcode刷题day27|贪心算法Part01(455.分发饼干、376. 摆动序列、53. 最大子序和)
  • 两个向量所在平面的法线,外积,叉积,行列式
  • GIT安装及集成到IDEA中操作步骤
  • Linux基础命令mount,umount详解
  • jmeter进行性能测试实践
  • 查看 .so 库(共享对象库)的依赖
  • linux驱动编程——等待队列
  • 显示器放大后,大漠识图识色坐标偏移解决方法
  • 【leetcode】122. 买卖股票的最佳时机 II
  • Linux下路由信息探测traceroute
  • UE4_Niagara基础实例—5、骨架网格体表面生成粒子及过滤骨骼位置生成粒子
  • 不同领域神经网络一般选择什么模型作为baseline(基准模型)
  • 【如何在Linux系统本地快速部署Leanote蚂蚁笔记】
  • SQL第9课——汇总数据
  • 命令模式
  • PCL 索引空间采样
  • golang fmt.Sprintf 引用前述变量
  • java将word转pdf