简单记录下,模板的使用,目前尚且还有一个问题就是,在重载加法运算符的过程中,使用malloc
产生的类
要怎么手动释放,目前在主函数好像不能直接free
了,不确定它会不会自动析构。
代码主要描述了一个简单的栈
,实现的过程,太久没用C++
了,算是复习一下,另外模板也是第二次用,重载运算符是第一次用,嗯,之前都完全没用到,虽然看过教程,这次算是动手实践,但是内存泄露还是存在,换成指针后允许手动释放内存,但还是不够优雅。
实际上想加入根据传入的数组初始化栈的,但是想了很久没想出要怎么在未知数组长度情况下,计算一个数组类型的一级指针参数的长度。
因为只是简单记录,而且是栈
,所以暂时不写注释了,有两个类,一个是None
,用于标识什么都没有,因为模板不允许用void*
,另一个是Rt
类,用于返回时携带操作成功或失败,以及必要的结果,如果没有结果,应该使用Rt
。
本工程作品均为本文作者撰写,无其他参考,允许使用在任何场景,作品遵循GPLv3.0
开源协议。转载本文请标注出处。
软件依赖 | 版本类型 | 版本号 |
---|---|---|
Lightly | Person | 0.7.9 |
template <typename T> Stack<T>::Stack() {
this->stack_array = (T*)malloc(sizeof(T) * this->default_stack_len);
this->len_max = this->default_stack_len;
this->len = 0;
}
template <typename T> Stack<T>::Stack(bool is_auto_expand) {
this->stack_array = (T*)malloc(sizeof(T) * this->default_stack_len);
this->len_max = this->default_stack_len;
this->len = 0;
this->is_auto_expand = true;
}
template <typename T> Stack<T>::Stack(int stack_len) {
this->stack_array = (T*)malloc(sizeof(T) * stack_len);
this->len_max = stack_len;
this->len = 0;
}
template <typename T> Stack<T>::~Stack() {
if (nullptr == this->stack_array) {
return;
}
free(this->stack_array);
this->stack_array = nullptr;
}
template <typename T> Stack<T>& Stack<T>::operator+(Stack& stack_add) {
Stack<T>* new_stack = (Stack<T>*)malloc(sizeof(Stack<T>));
new_stack->len = 0;
new_stack->len_max = this->len + stack_add.get_len();
if (nullptr != new_stack->stack_array) {
free(new_stack->stack_array);
}
new_stack->stack_array = (T*)malloc(sizeof(T) * new_stack->len_max);
for (int i = 0; i < this->len; i++) {
new_stack->push(this->stack_array[i]);
}
for (int i = 0; i < stack_add.get_len(); i++) {
new_stack->push(stack_add.stack_array[i]);
}
return *new_stack;
}
template <typename T> Stack<T>* Stack<T>::operator+(Stack& stack_add) {
Stack<T>* new_stack = (Stack<T>*)malloc(sizeof(Stack<T>));
new_stack->len = 0;
new_stack->len_max = this->len + stack_add.get_len();
if (nullptr != new_stack->stack_array) {
free(new_stack->stack_array);
}
new_stack->stack_array = (T*)malloc(sizeof(T) * new_stack->len_max);
for (int i = 0; i < this->len; i++) {
new_stack->push(this->stack_array[i]);
}
for (int i = 0; i < stack_add.get_len(); i++) {
new_stack->push(stack_add.stack_array[i]);
}
// You must free the point if you don't need it.
return new_stack;
}
template <typename T> Stack<T>& Stack<T>::operator+=(Stack& st) {
if (nullptr == this->stack_array) {
return *this;
}
if (this->len_max < this->len + st.len) {
this->len_max += st.len;
}
T* temp = (T*)malloc(sizeof(T) * this->len_max);
for (int i = 0; i < this->len; i++) {
temp[i] = this->stack_array[i];
}
free(this->stack_array);
this->stack_array = temp;
temp = nullptr;
for (int i = 0; i < st.len; i++) {
this->push(st.stack_array[i]);
}
return *this;
}
template <typename T> Rt<None> Stack<T>::push(T ele) {
Rt<None> rt;
if (this->len_max <= this->len) {
if (this->is_auto_expand) {
T *tmp = (T*)malloc(sizeof(T) * (this->len_max + this->default_stack_len));
this->len_max += this->default_stack_len;
memcpy(tmp, this->stack_array, this->len * sizeof(T));
free(this->stack_array);
this->stack_array = tmp;
} else {
rt.flag = false;
return rt;
}
}
++this->len;
this->stack_array[this->len - 1] = ele;
rt.flag = true;
return rt;
}
template <typename T> Rt<int> Stack<T>::pull() {
Rt<int> rt;
if (this->len <= 0) {
rt.flag = false;
return rt;
}
rt.data = this->stack_array[this->len - 1];
--this->len;
rt.flag = true;
return rt;
}
template <typename T> Rt<int> Stack<T>::read() {
Rt<int> rt;
if (this->len <= 0) {
rt.flag = false;
return rt;
}
rt.data = this->stack_array[len - 1];
rt.flag = true;
return rt;
}
template <typename T> int Stack<T>::get_len() {
return this->len;
}
template <typename T> void Stack<T>::print() {
for (int i = 0; i < this->len; i++) {
std::cout << this->stack_array[i] << "\t";
}
std::cout << std::endl;
}
template <typename T> void Stack<T>::auto_expand_set(bool option) {
this->is_auto_expand = option;
}
Stack<std::string> st1 = Stack<std::string>();
Stack<std::string> st2 = Stack<std::string>();
Stack<std::string> st3;
for (int i = 0; i < 8; i++) {
st1.push("abc");
}
for (int i = 0; i < 12; i++) {
st2.push("bcd");
}
std::cout << "Stack 01: ";
st1.print();
std::cout << "\nStack 02: ";
st2.print();
st1 += st2;
std::cout << "\nStack 01: ";
st1.print();
st3 = st1 + st2;
std::cout << "\nStack 03: ";
st3.print();
st1
会入栈8
个元素,st2
会入栈8
个元素st2
允许自动扩容,所以还会再入4
个元素st1
和st2
组合,st1
会扩容,st2
全部元素会追加在st1
末尾st3
将拥有实例,装载有组合后的st1
,再次与st2
组合#include
#include
#include
#include
class None {};
template <typename T> class Rt {
public:
bool flag;
T data;
};
template <typename T> class Stack {
template <typename S> friend void free_stack(Stack<S>* stack_free);
private:
int default_stack_len = 8;
bool is_auto_expand = false;
T* stack_array;
int len;
int len_max;
public:
Stack();
Stack(bool is_auto_expand);
Stack(int stack_len);
~Stack();
// Stack& operator+(Stack& stack_add);
Stack* operator+(Stack& stack_add);
Stack& operator+=(Stack& st);
void auto_expand_set(bool option);
int get_len();
void print();
Rt<None> push(T ele);
Rt<int> pull();
Rt<int> read();
};
template <typename T> Stack<T>* Stack<T>::operator+(Stack& stack_add) {
Stack<T>* new_stack = (Stack<T>*)malloc(sizeof(Stack<T>));
new_stack->len = 0;
new_stack->len_max = this->len + stack_add.get_len();
if (nullptr != new_stack->stack_array) {
free(new_stack->stack_array);
}
new_stack->stack_array = (T*)malloc(sizeof(T) * new_stack->len_max);
for (int i = 0; i < this->len; i++) {
new_stack->push(this->stack_array[i]);
}
for (int i = 0; i < stack_add.get_len(); i++) {
new_stack->push(stack_add.stack_array[i]);
}
// You must free the point if you don't need it.
return new_stack;
}
template <typename T> Stack<T>& Stack<T>::operator+=(Stack& st) {
if (nullptr == this->stack_array) {
return *this;
}
if (this->len_max < this->len + st.len) {
this->len_max += st.len;
}
T* temp = (T*)malloc(sizeof(T) * this->len_max);
for (int i = 0; i < this->len; i++) {
temp[i] = this->stack_array[i];
}
free(this->stack_array);
this->stack_array = temp;
temp = nullptr;
for (int i = 0; i < st.len; i++) {
this->push(st.stack_array[i]);
}
return *this;
}
template <typename T> Stack<T>::Stack() {
this->stack_array = (T*)malloc(sizeof(T) * this->default_stack_len);
this->len_max = this->default_stack_len;
this->len = 0;
}
template <typename T> Stack<T>::Stack(bool is_auto_expand) {
this->stack_array = (T*)malloc(sizeof(T) * this->default_stack_len);
this->len_max = this->default_stack_len;
this->len = 0;
this->is_auto_expand = true;
}
template <typename T> Stack<T>::Stack(int stack_len) {
this->stack_array = (T*)malloc(sizeof(T) * stack_len);
this->len_max = stack_len;
this->len = 0;
}
template <typename T> Stack<T>::~Stack() {
if (nullptr == this->stack_array) {
return;
}
free(this->stack_array);
this->stack_array = nullptr;
}
template <typename T> void Stack<T>::auto_expand_set(bool option) {
this->is_auto_expand = option;
}
template <typename T> int Stack<T>::get_len() {
return this->len;
}
template <typename T> void Stack<T>::print() {
for (int i = 0; i < this->len; i++) {
std::cout << this->stack_array[i] << "\t";
}
std::cout << std::endl;
}
template <typename T> Rt<None> Stack<T>::push(T ele) {
Rt<None> rt;
if (this->len_max <= this->len) {
if (this->is_auto_expand) {
T* tmp = (T*)malloc(sizeof(T) *
(this->len_max + this->default_stack_len));
this->len_max += this->default_stack_len;
memcpy(tmp, this->stack_array, this->len * sizeof(T));
// for (int i = 0; i < this->len; i ++) {
// tmp[i] = this->stack_array[i];
// }
free(this->stack_array);
this->stack_array = tmp;
} else {
rt.flag = false;
return rt;
}
}
++this->len;
this->stack_array[this->len - 1] = ele;
rt.flag = true;
return rt;
}
template <typename T> Rt<int> Stack<T>::pull() {
Rt<int> rt;
if (this->len <= 0) {
rt.flag = false;
return rt;
}
rt.data = this->stack_array[this->len - 1];
--this->len;
rt.flag = true;
return rt;
}
template <typename T> Rt<int> Stack<T>::read() {
Rt<int> rt;
if (this->len <= 0) {
rt.flag = false;
return rt;
}
rt.data = this->stack_array[len - 1];
rt.flag = true;
return rt;
}
template <typename T> void free_stack(Stack<T>* stack_free) {
stack_free->~Stack();
free(stack_free);
stack_free = nullptr;
}
int main() {
Stack<std::string> st1 = Stack<std::string>();
Stack<std::string> st2 = Stack<std::string>(true);
// Stack st3;
Stack<std::string>* st3;
for (int i = 0; i < 8; i++) {
st1.push("abc");
}
for (int i = 0; i < 12; i++) {
st2.push("bcd");
}
std::cout << "Stack 01: ";
st1.print();
std::cout << "\nStack 02: ";
st2.print();
st1 += st2;
std::cout << "\nStack 01: ";
st1.print();
st3 = st1 + st2;
std::cout << "\nStack 03: ";
st3->print();
free_stack(st3);
}
多看、多查、多练
[1] C++ Primer 第5版 中文版 (Stanley B. Lippman等著,王刚等译)
END