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