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;
}