类和对象

类和对象(实现一个顺序栈)

类定义格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class //	类名
{
public: // 公有类型 数据成员或成员函数
//类里面6个函数 以顺序栈为例
/*
构造函数 seqstack();
析构函数 ~seqstack();
左值拷贝构造函数 seqstack(const seqstack &src);
右值拷贝构造函数 资源转移 seqstack(seqstack &&src);
左值赋值重载函数 seqstack& operator=(const seqstack &src);
右值负值重载函数 资源转移 seqstack& operator=(seqstack &&src);
*/
private: // 私有类型 数据成员或成员函数
protected: // 保护类型 数据成员或成员函数
}

下面用类实现下顺序栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <iostream>
#include <ctime>
using namespace std;
class seqstack
{
public:
//构造函数 初始化 默认构造函数
seqstack(int _size=10)
{
cout<<"seqstack()构造函数"<<endl;
mstack=new int[_size]();
mtop=0;
msize=_size;
}
//析构函数 释放资源
~seqstack()
{
cout<<"~seqstack()析构函数"<<endl;
delete[]mstack;
mstack=nullptr;
}
//左值拷贝构造函数 seqstack s2(s1); seqstack s2=s1;
seqstack(const seqstack &src)
{
cout<<"seqstack(const seqstack &src)左值拷贝构造函数"<<endl;
mstack=new int[src.msize]();
for(int i=0;i<src.msize;i++)
mstack[i]=src.mstack[i];
mtop=src.mtop;
msize=src.msize;
}
//右值拷贝构造函数 拷贝的对象马上就完了,释放了,临时对象
seqstack(seqstack &&src)
{
cout<<"seqstack(seqstack &&src)右值拷贝构造函数"<<endl;
mstack=src.mstack;
mtop=src.mtop;
msize=src.msize;
src.mstack=nullptr;
}
//左值赋值重载函数 s1=s2; s1.operator=(s3) 为了支持连续赋值
seqstack& operator=(const seqstack &src)
{
cout<<"seqstack& operator=(const seqstack &src)左值赋值重载函数"<<endl;
if(this==&src) //防止自复制
return *this;
delete[]mstack; //释放当前对象原来的资源
mstack=new int[src.msize]; //根据引用资源的大小,重新开辟空间
for(int i=0;i<src.msize;i++)
mstack[i]=src.mstack[i];
mtop=src.mtop;
msize=src.msize;
return *this;
}
//右值赋值重载函数
seqstack& operator=(seqstack &&src)
{
cout<<"seqstack& operator=(seqstack &&src)右值赋值重载函数"<<endl;
delete[]mstack;
mstack=src.mstack;
mtop=src.mtop;
msize=src.msize;
src.mstack=nullptr;
return *this;
}
void push(int val)
{
if(full()) //扩容
expend(2*msize);
mstack[mtop++]=val;
}
void pop()
{
//if(this->Empty())
if(Empty())
return ;
mtop--;
}
int top()
{
if(this->Empty())
throw"stack is empty"; //throw 抛异常也可以结束一段代码逻辑
return mstack[mtop-1];
}
bool Empty()
{
return mtop==0;
}
bool full()
{
return mtop==msize;
}
private:
int *mstack;
int mtop;
int msize;
//扩容函数
void expend(int _size)
{
int *temp=new int[_size];
for(int i=0;i<msize;i++)
temp[i]=mstack[i];
delete[]mstack;
mstack=temp;
msize=_size;
}
};

如果主函数是这样的

1
2
3
4
5
6
7
8
9
int main()
{
seqstack s1;
seqstack s2;
seqstack s3;
s1=s2;
s2=(seqstack)(20);
return 0;
}

打印出来结果如下

1
2
3
4
5
6
7
8
9
10
seqstack()构造函数
seqstack()构造函数
seqstack()构造函数
seqstack& operator=(const seqstack &src)左值赋值重载函数
seqstack()构造函数
seqstack& operator=(seqstack &&src)右值赋值重载函数
~seqstack()析构函数
~seqstack()析构函数
~seqstack()析构函数
~seqstack()析构函数

首先前三个构造函数是定义s1,s2,s3构造的

下面的左值赋值重载函数是s1=s2这个赋值语句的

下面又是一个构造函数,这个是首先对20进行seqstack化

然后的右值赋值重载函数是将seqstack化的20赋值给s2,因为这个seqstack化的20是一个临时变量,不需要左赋值

接着这个析构函数是释放了20这个临时变量

最后三个析构函数是析构了s1,s2,s3这三个变量

如有错误,请多多关照