Compare commits
17 Commits
f956e9c5e2
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4c986179b4 | |||
| 9290e4c051 | |||
| 82619cea98 | |||
| cfd8dd3992 | |||
| 166515cf82 | |||
| 8c46e7a977 | |||
| 606fbc6ff1 | |||
| 994963d919 | |||
| 15ae1803d7 | |||
| c127a3a81b | |||
| 5ab334d200 | |||
| aae9aba049 | |||
| 08a390b0b1 | |||
| e5577ed3e5 | |||
| f5c016c6bb | |||
| 7b786b9b92 | |||
| be4a556f0b |
@@ -7,3 +7,15 @@
|
||||
#### day2: const 和#define 的区别, 引用(reference) 【重要】, 内联函数, 函数的默认值参数, 函数的占位参数, 函数重载和 extern "c", 类与对象的概念, 面向对象程序设计案例
|
||||
|
||||
#### day3: 对象的构造与析构, 构造函数的分类与调用, 拷贝构造函数的调用时机, 构造函数的调用规则, 深拷贝和浅拷贝, 多个对象的构造和析构(初始化列表, 类对象作为成员), explicit 关键字(禁止隐式转换), 动态创建对象(malloc/realloc/calloc 在堆中创建空间, new 关键字), 扩展 new 和 delete,
|
||||
|
||||
#### day4: static 静态成员, 类的单例设计模式, 对象的存储(this 指针与链式编程, const 修饰成员函数与类对象), 友元, 运算符重载
|
||||
|
||||
#### day5: =运算符的重载, () 函数调用重载, `注意: &&和|| 无法重载`,
|
||||
|
||||
#### day6: 多继承(同属一个超级父类)产生的问题, 多态,抽象类, 虚函数(virtual)与纯虚函数, 接口类的多继承, override-overload-redefined 的区别, 函数模版, 普通函数与带泛型函数的区别
|
||||
|
||||
#### day7: 函数模板, 类模板, 类模板与友元一起使用的情况, 类型转换函数(static_cast, dynamic_cast, const_cast, reinterpret_cast)
|
||||
|
||||
#### day8: 异常处理, STL(容器、算法、迭代器)
|
||||
|
||||
#### day9: STL-> string, vector, deque, stack
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 166 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 343 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 212 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 120 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 97 KiB |
Executable
+289
@@ -0,0 +1,289 @@
|
||||
## 二、STL容器II
|
||||
|
||||
### 2.1 queue 容器
|
||||
|
||||
#### 2.1.1 queue概念
|
||||
|
||||
> Queue 是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口,queue
|
||||
> 容器允许从一端新增元素,从另一端移除元素。
|
||||
|
||||

|
||||
|
||||
#### 2.1.2 queue 没有迭代器
|
||||
|
||||
Queue 所有元素的进出都必须符合”先进先出”的条件,只有 queue 的顶端元素,才
|
||||
有机会被外界取用。Queue 不提供遍历功能,也不提供迭代器。
|
||||
|
||||
|
||||
|
||||
#### 2.1.3 常用API
|
||||
|
||||
##### 2.1.3.1 构造函数
|
||||
|
||||
```c++
|
||||
queue<T> queT; //queue 采用模板类实现,queue 对象的默认构造形式:
|
||||
queue(const queue &que);//拷贝构造函数
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 2.1.3.2 存取、插入和删除
|
||||
|
||||
```c++
|
||||
void push(elem); //往队尾添加元素
|
||||
void pop(); //从队头移除第一个元素
|
||||
T back(); //返回最后一个元素
|
||||
T front(); //返回第一个元素
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 2.1.3.3 赋值与大小
|
||||
|
||||
```c++
|
||||
queue& operator=(const queue &que);//重载等号操作符
|
||||
|
||||
empty();//判断队列是否为空
|
||||
size();//返回队列的大小
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 2.2 list 容器
|
||||
|
||||
#### 2.2.1 list 概念
|
||||
|
||||
list(链表)是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
|
||||
|
||||
链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。
|
||||
|
||||
每个结点包括两个部分:
|
||||
|
||||
```
|
||||
1)存储数据元素的数据域,
|
||||
2)存储下一个结点地址的指针域
|
||||
```
|
||||
|
||||
list与vector的比较:
|
||||
|
||||
```
|
||||
1) 相对于vector 的连续线性空间,list 就显得负责许多,每次插入或者删除一个元素,就是配置或者释放一个元素的空间。不浪费多余的空间,且插入与移除元素的操作是常数时间(稳定)。
|
||||
2)list和vector 是两个最常被使用的容器, 但list是由双向链表实现的。
|
||||
3)list插入操作和删除操作都不会造成原有 list 迭代器的失效。 【重要特性】
|
||||
```
|
||||
|
||||
<img src="./readme.assets/image-20230804075335829.png" width="400">
|
||||
|
||||
list特点:
|
||||
|
||||
```
|
||||
1)采用动态存储分配,不会造成内存浪费和溢出
|
||||
2)链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
|
||||
3)链表灵活,但是空间和时间额外耗费较大
|
||||
```
|
||||
|
||||
#### 2.2.2 list 的迭代器
|
||||
|
||||
List 不能像 vector 一样以普通指针作为迭代器,因为其节点不能保证在同一块连续的内存空间上。。List 迭代器必须有能力指向 list 的节点,并有能力进行正确的递增、递减、取值、成员存取操作。**递增**时指向下一个节点,**递减**时指向上一个节点,**取值**时取的是节点的数据值,**成员取用**时取的是节点的成员。
|
||||
|
||||
另外,list 是一个双向链表,迭代器必须能够具备前移、后移的能力,所以 list 容器提供的是 Bidirectional Iterators.(双向的迭代器)。
|
||||
|
||||
List 有一个重要的性质,插入操作和删除操作都不会造成原有 list 迭代器的失效。
|
||||
|
||||
<font color=red>【注意】list的迭代器,不支持`+n`操作。</font>
|
||||
|
||||
#### 2.2.3 list 数据结构
|
||||
|
||||
> list 容器不仅是一个双向链表,而且还是一个循环的双向链表。
|
||||
|
||||
#### 2.2.4 常用API
|
||||
|
||||
##### 2.2.4.1 构造函数
|
||||
|
||||
```c++
|
||||
list<T> lstT;//list 采用采用模板类实现,对象的默认构造形式:
|
||||
list(beg,end);//构造函数将[beg, end)区间中的元素拷贝给本身。
|
||||
list(n,elem);//构造函数将 n 个 elem 拷贝给本身。
|
||||
list(const list &lst);//拷贝构造函数
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 2.2.4.2 插入和删除
|
||||
|
||||
```c++
|
||||
push_back(elem);//在容器尾部加入一个元素
|
||||
pop_back();//删除容器中最后一个元素
|
||||
push_front(elem);//在容器开头插入一个元素
|
||||
pop_front();//从容器开头移除第一个元素
|
||||
insert(pos,elem);//在 pos 位置插 elem 元素的拷贝,返回新数据的位置。
|
||||
insert(pos,n,elem);//在 pos 位置插入 n 个 elem 数据,无返回值。
|
||||
insert(pos,beg,end);//在 pos 位置插入[beg,end)区间的数据,无返回值。
|
||||
clear();//移除容器的所有数据
|
||||
|
||||
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
|
||||
erase(pos);//删除 pos 位置的数据,返回下一个数据的位置。
|
||||
remove(elem);//删除容器中所有与 elem 值匹配的元素
|
||||
```
|
||||
|
||||
##### 2.2.4.3 大小
|
||||
|
||||
```c++
|
||||
size();//返回容器中元素的个数
|
||||
empty();//判断容器是否为空
|
||||
resize(num);//重新指定容器的长度为 num, 若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除
|
||||
resize(num, elem);
|
||||
```
|
||||
|
||||
##### 2.2.4.4 赋值
|
||||
|
||||
```c++
|
||||
assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。
|
||||
assign(n, elem); //将 n 个 elem 拷贝赋值给本身。
|
||||
list& operator=(const list &lst); //重载等号操作符
|
||||
swap(lst); //将 lst 与本身的元素互换。
|
||||
```
|
||||
|
||||
##### 2.2.4.5 读取
|
||||
|
||||
```
|
||||
front();//返回第一个元素。
|
||||
back();//返回最后一个元素
|
||||
```
|
||||
|
||||
##### 2.2.4.6 反转和排序
|
||||
|
||||
```
|
||||
reverse(); //反转链表
|
||||
sort(); //list 排序
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 2.3 set/multiset 容器
|
||||
|
||||
#### 2.3.1 set概念
|
||||
|
||||
set 的特性是所有元素都会根据元素的键值自动被排序。
|
||||
|
||||
set 的元素即是键值又是实值, 不允许两个元素有相同的键值。
|
||||
|
||||
set 的 iterator 是一种 const_iterator, 不允许修改set的键值。
|
||||
|
||||
set 拥有和 list 某些相同的性质,当对容器中的元素进行插入操作或者删除操作的
|
||||
时候,操作之前的迭代器,在操作完成之后依然有效,被删除的那个元素的迭代器必然是一个例外。
|
||||
|
||||
#### 2.3.2 set数据结构
|
||||
|
||||
multiset 特性及用法和 set 完全相同,唯一的差别在于它允许键值重复。set 和multiset 的底层实现是红黑树,红黑树为平衡二叉树的一种。
|
||||
|
||||
二叉树就是任何节点最多只允许有两个字节点。分别是左子结点和右子节点:
|
||||
|
||||
<img src="./readme.assets/image-20230804083406386.png" width="300">
|
||||
|
||||
二叉搜索树,是指二叉树中的节点按照一定的规则进行排序,使得对二叉树中元素访问更加高效:
|
||||
|
||||
<img src="./readme.assets/image-20230804083459911.png" width=400>
|
||||
|
||||
二叉搜索树的放置规则是:
|
||||
|
||||
任何节点的元素值一定大于其左子树中的每一个节点的元素值,并且小于其右子树的值。因此从根节点一直向左走,一直到无路可走,即得到最小值,一直向右走,直至无路可走,可得到最大值。那么在二叉搜索树中找到最大元素和最小元素是非常简单的事情。
|
||||
|
||||
如上图所示:那么当一个二叉搜索树的左子树和右子树不平衡的时候,那么搜索依据上图表示,搜索 9 所花费的时间要比搜索 17 所花费的时间要多,由于我们的输入或者经过我们插入或者删除操作,二叉树失去平衡,造成搜索效率降低。
|
||||
|
||||
<img src="./readme.assets/image-20230804083751044.png" width=400>
|
||||
|
||||
#### 2.3.3 常用API
|
||||
|
||||
##### 2.3.3.1 构造函数
|
||||
|
||||
```c++
|
||||
set<T> st;//set 默认构造函数:
|
||||
mulitset<T> mst; //multiset 默认构造函数:
|
||||
set(const set &st);//拷贝构造函数
|
||||
```
|
||||
|
||||
##### 2.3.3.2 赋值和大小
|
||||
|
||||
```c++
|
||||
set& operator=(const set &st);//重载等号操作符
|
||||
swap(st);//交换两个集合容器
|
||||
|
||||
size();//返回容器中元素的数目
|
||||
empty();//判断容器是否为空
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 2.3.3.3 插入和删除
|
||||
|
||||
```
|
||||
insert(elem); //在容器中插入元素。
|
||||
clear(); //清除所有元素
|
||||
erase(pos); //删除 pos 迭代器所指的元素,返回下一个元素的迭代器。
|
||||
erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
|
||||
erase(elem); //删除容器中值为 elem 的元素。
|
||||
```
|
||||
|
||||
##### 2.3.3.4 查找
|
||||
|
||||
```c++
|
||||
find(key); //查找键 key 是否存在,若存在,返回该键的元素的迭代器;若不存在,返
|
||||
回 set.end();
|
||||
count(key);//查找键 key 的元素个数
|
||||
lower_bound(keyElem);//返回第一个 key>=keyElem 元素的迭代器。
|
||||
upper_bound(keyElem);//返回第一个 key>keyElem 元素的迭代器。
|
||||
equal_range(keyElem);//返回容器中 key 与 keyElem 相等的上下限的两个迭代器。
|
||||
```
|
||||
|
||||
##### 2.3.3.5 set 排序规则
|
||||
|
||||
> set自动排序, 但可以改变它的排序规则,默认从小到大。
|
||||
|
||||
自定义排序规则,可以使用struct或class, 声明 `bool operator(v1, v2)`仿函数重载。
|
||||
|
||||
|
||||
|
||||
#### 2.3.4 对组(pair)
|
||||
|
||||
对组(pair)将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值可
|
||||
以分别用 pair 的两个公有属性 first 和 second 访问。
|
||||
|
||||
```
|
||||
类模板:template <class T1, class T2> struct pair
|
||||
```
|
||||
|
||||
用法一:
|
||||
|
||||
```c++
|
||||
pair<string, int> pair1(string("name"), 20);
|
||||
cout << pair1.first << endl;
|
||||
cout << pair1.second << endl;
|
||||
```
|
||||
|
||||
用法二:
|
||||
|
||||
```c++
|
||||
pair<string, int> pair2 = make_pair("name", 30);
|
||||
cout << pair2.first << endl;
|
||||
cout << pair2.second << endl;
|
||||
```
|
||||
|
||||
用法三:
|
||||
|
||||
```c++
|
||||
pair<string, int> pair3 = pair2;
|
||||
cout << pair3.first << endl;
|
||||
cout << pair3.second << endl;
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 2.4 map/multimap 容器
|
||||
|
||||
Map 的特性是所有元素都会根据元素的键值自动排序。
|
||||
|
||||
Map 所有的元素都是pair,同时拥有实值和键值,pair 的第一元素被视为键值,第二元素被视为实值,map 不允许两个元素有相同的键值。
|
||||
|
||||
multimap 和 map 的操作类似,唯一区别 multimap 键值可重复。
|
||||
map 和 multimap 都是以红黑树为底层实现机制。
|
||||
@@ -0,0 +1,33 @@
|
||||
// 函数对象
|
||||
// 仿函数: 一元,二元仿函数
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 一元仿函数
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A(int n) : n(n) {}
|
||||
int n;
|
||||
// 重载 operator() 运算符,只要调用 A 对象的 (int x) ,就会给对象的对应成员对象加一个 x
|
||||
A &operator()(int i)
|
||||
{
|
||||
this->n += i;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
void print(A a, int n) // A a = A(30)
|
||||
{
|
||||
a(n);
|
||||
cout << "a.n = " << a.n << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// 打印 a 对象的值加额外的值的结果
|
||||
print(A(20), 3); // A(20) 会创建一个匿名对象
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// 谓词
|
||||
// gt 大于, ge 大于等于
|
||||
// lt 小于, le 小于等于
|
||||
// eq 等于, ne 小于等于
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class GTFive // 一元谓词
|
||||
{
|
||||
public:
|
||||
bool operator()(int n)
|
||||
{
|
||||
return n > 5;
|
||||
}
|
||||
};
|
||||
|
||||
class GT // 二元谓词
|
||||
{
|
||||
public:
|
||||
bool operator()(const int &n1, const int &n2)
|
||||
{
|
||||
return n1 > n2;
|
||||
}
|
||||
};
|
||||
|
||||
void printGTF(GTFive gtf, int *p, int size)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (gtf(p[i]))
|
||||
cout << p[i] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void print(int *p, int size, GT gt, int n)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (gt(p[i], n))
|
||||
cout << p[i] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int ms[] = {1, 2, 4, 7, 9, 20};
|
||||
cout << "大于 5 的元素" << endl;
|
||||
printGTF(GTFive(), ms, 6);
|
||||
|
||||
cout << "大于 7 的元素" << endl;
|
||||
print(ms, 6, GT(), 7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// 算术类函数对象
|
||||
// 算术类函数对象
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// template <typename T>
|
||||
void print(typename set<int>::const_iterator start,
|
||||
typename set<int>::const_iterator end, plus<int> pl, int m)
|
||||
{
|
||||
for (; start != end; start++)
|
||||
{
|
||||
cout << pl(*start, m) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void print(typename set<int>::const_iterator start,
|
||||
typename set<int>::const_iterator end, multiplies<int> mul, int m)
|
||||
{
|
||||
for (; start != end; start++)
|
||||
{
|
||||
cout << mul(*start, m) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 3, 4, 8, 5, 1, 2};
|
||||
// set 会自动过滤重复,并排序
|
||||
set<int> s(m, m + sizeof(m) / sizeof(m[0]));
|
||||
print(s.begin(), s.end(), plus<int>(), 1);
|
||||
print(s.begin(), s.end(), multiplies<int>(), 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// template <typename T>
|
||||
void print(typename set<int>::const_iterator start,
|
||||
typename set<int>::const_iterator end, plus<int> pl, int m)
|
||||
{
|
||||
for (; start != end; start++)
|
||||
{
|
||||
cout << pl(*start, m) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void print(typename set<int>::const_iterator start,
|
||||
typename set<int>::const_iterator end, multiplies<int> mul, int m)
|
||||
{
|
||||
for (; start != end; start++)
|
||||
{
|
||||
cout << mul(*start, m) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void show(int n)
|
||||
{
|
||||
cout << n << " ";
|
||||
}
|
||||
|
||||
// 二元仿函数
|
||||
class PrintPlus : public binary_function<int, int, void>
|
||||
{
|
||||
public:
|
||||
void operator()(const int &n1, const int &n2) const
|
||||
{
|
||||
cout << n1 << "+" << n2 << " = " << n1 + n2 << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 3, 4, 8, 5, 1, 2};
|
||||
// set 会自动过滤重复,并排序
|
||||
set<int> s(m, m + sizeof(m) / sizeof(m[0]));
|
||||
// print(s.begin(), s.end(), plus<int>(), 1);
|
||||
// print(s.begin(), s.end(), multiplies<int>(), 3);
|
||||
|
||||
// for_each(s.begin(), s.end(), show);
|
||||
// cout << endl;
|
||||
|
||||
// PrintPlus 测试
|
||||
// for (int i = 0; i < 6; i++)
|
||||
for_each(s.begin(), s.end(), bind1st(PrintPlus(), i));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class PrintGt5Adapter : public binary_function<int, int, void>
|
||||
{
|
||||
public:
|
||||
void operator()(const int &n1, const int &n2) const
|
||||
{
|
||||
if (n1 > n2)
|
||||
cout << n1 << " ";
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 3, 4, 8, 5, 1, 2};
|
||||
set<int> s(m, m + sizeof(m) / sizeof(m[0]));
|
||||
|
||||
for_each(s.begin(), s.end(), bind2nd(PrintGt5Adapter(), 2));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// 取反适配器
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
// 自定义一个适配器,只需要容器中元素即可。
|
||||
class GT5 : public unary_function<int, bool>
|
||||
{
|
||||
public:
|
||||
bool operator()(const int &n) const
|
||||
{
|
||||
return n > 5;
|
||||
}
|
||||
};
|
||||
|
||||
class GTN : public binary_function<int, int, bool>
|
||||
{
|
||||
public:
|
||||
bool operator()(const int &n1, const int &n2) const
|
||||
{
|
||||
return n1 > n2;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 2, 3, 5, 10};
|
||||
vector<int> v;
|
||||
v.assign(m, m + sizeof(m) / sizeof(m[0]));
|
||||
|
||||
// find_if(start, end, _callback) 返回查找到的第一个迭代器的位置
|
||||
vector<int>::iterator ret = find_if(v.begin(), v.end(), not1(bind2nd(greater<int>(), 3)));
|
||||
cout << *ret << endl;
|
||||
|
||||
ret = find_if(v.begin(), v.end(), GT5());
|
||||
cout << *ret << endl;
|
||||
|
||||
ret = find_if(v.begin(), v.end(), bind2nd(GTN(), 3));
|
||||
cout << *ret << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// 函数指针适配
|
||||
// 使用 ptr_fun<>() 适配函数指针
|
||||
// <> 中的第一个参数是函数指针的类型,第二个参数是函数指针的参数类型,第三个参数是函数指针的返回值类型
|
||||
// bind1st() 和 bind2nd() 适配函数对象
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool gtn(int n1, int n2)
|
||||
{
|
||||
return n1 > n2;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 2, 3, 5, 10};
|
||||
vector<int> v;
|
||||
v.assign(m, m + sizeof(m) / sizeof(m[0]));
|
||||
|
||||
vector<int>::iterator ret = find_if(v.begin(), v.end(), bind2nd(ptr_fun<int, int, bool>(gtn), 3));
|
||||
cout << *ret << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// mem_fn 有两个重载版本:
|
||||
// 用法1:mem_fn(&MyClass::printMessage) 用于将成员函数转换为函数对象
|
||||
// 用法2:mem_fn(&MyClass::printMessage)(&obj, "hello world") 用于调用成员函数
|
||||
// mem_fn 是一个函数模板,它接受一个成员函数指针或成员函数引用,并返回一个函数对象,该对象可以调用相应的成员函数。
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Stu
|
||||
{
|
||||
private:
|
||||
string name;
|
||||
int age;
|
||||
|
||||
public:
|
||||
Stu(const string &name, int age) : name(name), age(age) {}
|
||||
|
||||
public:
|
||||
void show()
|
||||
{
|
||||
cout << "name is " << name << ", age is " << age << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
vector<Stu> vs;
|
||||
vs.push_back(Stu("disen", 18));
|
||||
vs.push_back(Stu("lucy", 20));
|
||||
vs.push_back(Stu("jack", 15));
|
||||
vs.push_back(Stu("mack", 19));
|
||||
|
||||
// 遍历容器中所有成员,成员函数作为仿函数时,则通过容器成员调用它的仿函数
|
||||
for_each(vs.begin(), vs.end(), mem_fun_ref(&Stu::show));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
using namespace std;
|
||||
using namespace std::placeholders;
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 2, 3, 5, 10};
|
||||
vector<int> v;
|
||||
v.assign(m, m + sizeof(m) / sizeof(m[0]));
|
||||
|
||||
int target = 3;
|
||||
|
||||
// 使用 std::bind 适配 std::equal_to
|
||||
vector<int>::iterator ret = adjacent_find(v.begin(), v.end(), bind(equal_to<int>(), _1, 3));
|
||||
cout << *(++ret) << endl;
|
||||
|
||||
if (ret != v.end())
|
||||
{
|
||||
cout << "Found adjacent elements equal to " << target << "." << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "No adjacent elements equal to " << target << " found." << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const list<T> &lst)
|
||||
{
|
||||
for (typename list<T>::const_iterator it = lst.begin(); it != lst.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
list<int> lst1(6, 5); // 6 个 5
|
||||
print(lst1);
|
||||
|
||||
string s1 = "abcdefg";
|
||||
|
||||
// 将 string 字符串转换为 list
|
||||
list<char> lst2(s1.begin(), s1.end());
|
||||
print(lst2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const list<T> &lst)
|
||||
{
|
||||
for (typename list<T>::const_iterator it = lst.begin(); it != lst.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string s = "abcdefg";
|
||||
|
||||
// 将 string 字符串转换为 list
|
||||
list<char> l(s.begin(), s.end());
|
||||
int size = l.size(); // 获取大小
|
||||
print(l);
|
||||
|
||||
// list 手写逆序
|
||||
list<char>::iterator it = l.begin(); // 迭代器指向第一个元素
|
||||
for (int i = 0; i < size; i++) // 逆序 size 次
|
||||
{
|
||||
it = l.insert(it, l.back()); // 将最后一个元素插入到第一个元素之前
|
||||
it++; // 迭代器指向下一个元素
|
||||
l.pop_back(); // 删除最后一个元素
|
||||
}
|
||||
|
||||
print(l);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const list<T> &lst)
|
||||
{
|
||||
for (typename list<T>::const_iterator it = lst.begin(); it != lst.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string s = "abcdefg";
|
||||
list<char> l(s.begin(), s.end());
|
||||
|
||||
// 删除 cde
|
||||
// list<char>::iterator it = find(l.begin(), l.end(), 'c');
|
||||
// l.erase(it, find(l.begin(), l.end(), 'e'));
|
||||
|
||||
list<char>::iterator it = l.begin(); // 迭代器指向第一个元素
|
||||
for (int i = 0; i < 2; i++) // 迭代器指向第三个元素
|
||||
it++;
|
||||
list<char>::iterator it2 = it; // 迭代器指向第三个元素
|
||||
for (int i = 0; i < 3; i++) // 迭代器指向第六个元素
|
||||
it2++;
|
||||
l.erase(it, it2); // 删除第三个到第五个元素
|
||||
|
||||
print(l); // a b f g
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const list<T> &lst)
|
||||
{
|
||||
for (typename list<T>::const_iterator it = lst.begin(); it != lst.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string s = "abcdefg";
|
||||
list<char> l(s.begin(), s.end());
|
||||
print(l);
|
||||
l.reverse(); // 逆序
|
||||
print(l);
|
||||
|
||||
int m[] = {6, 4, 2, 0, 8, 6, 4};
|
||||
list<int> l2(m, m + 7);
|
||||
print(l2);
|
||||
l2.sort(); // 排序
|
||||
print(l2);
|
||||
l2.reverse(); // 逆序
|
||||
print(l2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
map<int, string> ms;
|
||||
|
||||
// 1. insert()函数
|
||||
// map 在插入时会自动根据 map 的键来排序
|
||||
ms.insert(pair<int, string>(1, "张三")); // pair<int, string>是map<int, string>::value_type的类型
|
||||
ms.insert(pair<int, string>(4, "李四"));
|
||||
ms.insert(make_pair(3, "王五")); // make_pair()函数可以自动推导出类型
|
||||
ms.insert(map<int, string>::value_type(2, "赵六")); // value_type是map<int, string>的类型
|
||||
ms[5] = "田七"; // 通过下标的方式插入数据
|
||||
|
||||
map<int, string>::iterator it = ms.begin();
|
||||
for (; it != ms.end(); it++)
|
||||
{
|
||||
// cout << "sid = " << it->first << ",name = " << it->second << endl;
|
||||
cout << "sid = " << (*it).first << ",name = " << (*it).second << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// 使用 map 来解决括号匹配
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string left_c = "{[(";
|
||||
map<char, char> map1;
|
||||
|
||||
bool valid(const char *p)
|
||||
{
|
||||
stack<char> stk;
|
||||
int max_depth = 0;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
const char &cp = *p;
|
||||
|
||||
// if (left_c.find(cp) != string::npos) // 如果当前拿到的是左括号
|
||||
if (left_c.find(cp) != -1) // 如果当前拿到的是左括号
|
||||
{
|
||||
// 入栈
|
||||
stk.push(*p);
|
||||
}
|
||||
else // 如果当前拿到的是右括号
|
||||
{
|
||||
// 弹栈
|
||||
if (stk.empty())
|
||||
return false;
|
||||
|
||||
const char &top = stk.top();
|
||||
if (map1[cp] != top)
|
||||
return false;
|
||||
|
||||
// 当前左右匹配的后续操作
|
||||
// 求最大深度
|
||||
if (max_depth < stk.size())
|
||||
max_depth = stk.size();
|
||||
|
||||
// 弹栈前判断最大深度
|
||||
stk.pop();
|
||||
}
|
||||
p++;
|
||||
}
|
||||
cout << "当前括号栈的最大深度为: " << max_depth << endl;
|
||||
|
||||
return stk.empty();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
map1.insert(make_pair('}', '{'));
|
||||
map1.insert(make_pair(']', '['));
|
||||
map1.insert(make_pair(')', '('));
|
||||
|
||||
cout << valid("{[()]}[[[[[()]]]]]") << endl;
|
||||
cout << valid("{[())}") << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
map<int, string> m;
|
||||
m.insert(make_pair(1, "disen"));
|
||||
m.insert(make_pair(2, "lucy"));
|
||||
cout << m.size() << endl;
|
||||
m.erase(1); // 删除键值为 1 的元素
|
||||
cout << m.size() << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
map<int, string> m;
|
||||
m.insert(make_pair(1, "disen"));
|
||||
m.insert(make_pair(2, "lucy"));
|
||||
m.insert(make_pair(3, "jack"));
|
||||
|
||||
map<int, string>::const_iterator it = m.find(3);
|
||||
|
||||
if (it == m.end())
|
||||
{
|
||||
cout << "未查找到" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
const pair<int, string> &p = *it;
|
||||
cout << p.first << ", " << p.second << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const set<T> &s)
|
||||
{
|
||||
for (typename set<T>::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void print(const multiset<T> &s)
|
||||
{
|
||||
for (typename multiset<T>::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 3, 2, 3, 4};
|
||||
set<int> s(m, m + 6);
|
||||
print(s); // set 会自动去重,输出 1 2 3 4
|
||||
|
||||
multiset<int> ms(m, m + 6);
|
||||
print(ms); // multiset 不会自动去重,输出 1 2 2 3 3 4
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const set<T> &s)
|
||||
{
|
||||
for (typename set<T>::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {5, 12, 16, 21, 22, 27, 29, 30};
|
||||
set<int> s(m, m + 8);
|
||||
print(s); // set 键值自动排序,且不重复
|
||||
|
||||
// 查看大于等于 22 值的所有元素
|
||||
cout << "查看大于等于 22 值的所有元素: " << endl;
|
||||
set<int>::iterator it = s.lower_bound(22); // 返回第一个大于等于 22 的元素的迭代器
|
||||
while (it != s.end())
|
||||
{
|
||||
cout << *it << ' ';
|
||||
++it;
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
// 查找小于等于 22 值的所有元素
|
||||
cout << "查找小于等于 22 值的所有元素: " << endl;
|
||||
// it = s.upper_bound(22); // 返回第一个大于 22 的元素的迭代器
|
||||
// for (; it != s.begin();)
|
||||
// {
|
||||
// --it;
|
||||
// cout << *it << ' ';
|
||||
// }
|
||||
// cout << endl;
|
||||
|
||||
// 查找小于等于 22 值的所有元素(另一种写法)
|
||||
it = s.lower_bound(22);
|
||||
while (it != s.begin())
|
||||
{
|
||||
--it;
|
||||
cout << *it << ' ';
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// 自定义排序
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 自定义规则
|
||||
template <typename T>
|
||||
class MySort
|
||||
{
|
||||
public:
|
||||
bool operator()(const T &a, const T &b)
|
||||
{
|
||||
return a > b; // 从小到大排序
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// 使用 set 时,添加自定义排序规则
|
||||
set<int, MySort<int> > s1;
|
||||
s1.insert(20);
|
||||
s1.insert(30);
|
||||
s1.insert(1);
|
||||
s1.insert(8);
|
||||
|
||||
set<int, MySort<int> >::iterator it = s1.begin(); // <int, MySort<int>> 可以省略
|
||||
while (it != s1.end())
|
||||
{
|
||||
cout << *it << ' ';
|
||||
++it;
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// 自定义排序
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 自定义规则
|
||||
template <typename T>
|
||||
class MySort
|
||||
{
|
||||
public:
|
||||
bool operator()(const T &a, const T &b)
|
||||
{
|
||||
return a > b; // 从小到大排序
|
||||
}
|
||||
};
|
||||
|
||||
class Student
|
||||
{
|
||||
public:
|
||||
string name;
|
||||
int age;
|
||||
float score;
|
||||
|
||||
public:
|
||||
Student(const string &name, int age, float score)
|
||||
{
|
||||
this->name = name;
|
||||
this->age = age;
|
||||
this->score = score;
|
||||
}
|
||||
};
|
||||
|
||||
class MyStudentByAgeSort
|
||||
{
|
||||
public:
|
||||
bool operator()(const Student &s1, const Student &s2)
|
||||
{
|
||||
return s1.age > s2.age;
|
||||
}
|
||||
};
|
||||
|
||||
class MyStudentByScoreSort
|
||||
{
|
||||
public:
|
||||
bool operator()(const Student &s1, const Student &s2)
|
||||
{
|
||||
return s1.score > s2.score;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Student[] *stus = new Student[3]{Student("张三", 18, 100), Student("李四", 20, 90), Student("王五", 19, 95)};
|
||||
set<Student, MyStudentByAgeSort> s2;
|
||||
s2............................
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
// pair 是一个模板类,有两个模板参数,
|
||||
// 用于存储两个数据,可以分别指定两个数据的类型
|
||||
pair<int, string> p1(1, "张三");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// 对组(pair)
|
||||
// 将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值可
|
||||
// 以分别用 pair 的两个公有属性 first 和 second 访问。
|
||||
|
||||
// 类模板:template<class T1, class T2> class pair
|
||||
|
||||
// 用法一:
|
||||
|
||||
// pair<string, int> pair1(string("name"), 20);
|
||||
// cout << pair1.first << endl;
|
||||
// cout << pair1.second << endl;
|
||||
|
||||
// 用法二:
|
||||
|
||||
// pair<string, int> pair2 = make_pair("name", 30);
|
||||
// cout << pair2.first << endl;
|
||||
// cout << pair2.second << endl;
|
||||
|
||||
// 用法三:
|
||||
|
||||
// pair<string, int> pair3 = pair2; // 拷贝构造函数
|
||||
// cout << pair3.first << endl;
|
||||
// cout << pair3.second << endl;
|
||||
|
||||
// 如:
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
pair<int, string> p1(1, "disen");
|
||||
pair<int, string> p2 = make_pair(2, "lucy");
|
||||
cout << "id = " << p1.first << ", name = " << p1.second << endl;
|
||||
cout << "id = " << p2.first << ", name = " << p2.second << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// 类的静态成员变量的声明、初始化与访问
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
static int x;
|
||||
};
|
||||
|
||||
int A::x = 20; // 静态变量初始化,静态成员变量初始化时不需要 static
|
||||
|
||||
int main()
|
||||
{
|
||||
A a1, a2;
|
||||
// 访问类的静态成员: 1) A::x, 2) 对象名.x
|
||||
cout << "A::x = " << A::x << endl; // 20
|
||||
A::x = 30;
|
||||
cout << "a1.x = " << a1.x << endl; // 30
|
||||
cout << "a2.x = " << a2.x << endl; // 30
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// 重载 C++ 的 << 输出流运算符
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
friend ostream &operator<<(ostream &cout, A &a);
|
||||
|
||||
private:
|
||||
int x, y;
|
||||
|
||||
public:
|
||||
A(int x, int y) : x(x), y(y) {}
|
||||
};
|
||||
|
||||
// << 输出运算符重载
|
||||
ostream &operator<<(ostream &cout, A &a)
|
||||
{
|
||||
// x, y 是 A 类的私有成员
|
||||
cout << "a.x : " << a.x << ", a.y : " << a.y << endl;
|
||||
return cout;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
A a1(1, 2);
|
||||
cout << a1;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// 重载 C++ 的 >> 输入流运算符
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Worker
|
||||
{
|
||||
friend istream &operator>>(istream &cin, Worker &obj);
|
||||
friend ostream &operator<<(ostream &cout, Worker &obj);
|
||||
|
||||
private:
|
||||
string name;
|
||||
int salary;
|
||||
};
|
||||
|
||||
istream &operator>>(istream &cin, Worker &obj)
|
||||
{
|
||||
cout << "Name: ";
|
||||
cin >> obj.name;
|
||||
cout << "salary: ";
|
||||
cin >> obj.salary;
|
||||
return cin;
|
||||
}
|
||||
|
||||
ostream &operator<<(ostream &cout, Worker &obj)
|
||||
{
|
||||
cout << "Worker name is " << obj.name << ", salary is " << obj.salary << endl;
|
||||
return cout;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Worker w1;
|
||||
cin >> w1;
|
||||
cout << w1;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// 重载运算符
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Num
|
||||
{
|
||||
private:
|
||||
int n;
|
||||
|
||||
public:
|
||||
explicit Num(int n) : n(n)
|
||||
{
|
||||
}
|
||||
bool operator>(int other)
|
||||
{
|
||||
return this->n > other;
|
||||
}
|
||||
bool operator<(int other)
|
||||
{
|
||||
return this->n < other;
|
||||
}
|
||||
bool operator>(Num &other)
|
||||
{
|
||||
return this->n > other.n;
|
||||
}
|
||||
bool operator<(Num &other)
|
||||
{
|
||||
return this->n < other.n;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
Num n1(atoi(argv[1])), n2(atoi(argv[2]));
|
||||
if (n1 > 20)
|
||||
{
|
||||
cout << "n1 大于 20" << endl;
|
||||
|
||||
if (n1 < n2)
|
||||
{
|
||||
cout << "n1 小于 n2" << endl;
|
||||
}
|
||||
}
|
||||
if (n1 > n2)
|
||||
{
|
||||
cout << "n1 大于 n2" << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// 重载 * 和 ->
|
||||
// 注意: * 和 -> 的重载不能有参数
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
int x;
|
||||
|
||||
public:
|
||||
explicit A(int x) : x(x) {}
|
||||
void printA()
|
||||
{
|
||||
cout << "x = " << x << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class B
|
||||
{
|
||||
private:
|
||||
A *mA;
|
||||
|
||||
public:
|
||||
B(int x) : mA(new A(x))
|
||||
{
|
||||
}
|
||||
|
||||
A *operator->()
|
||||
{
|
||||
return mA;
|
||||
}
|
||||
A &operator*()
|
||||
{
|
||||
return *mA;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
B b(20);
|
||||
// b -> 执行 B 类的 -> 重载,返回 A 类的对象的指针
|
||||
b->printA();
|
||||
|
||||
B b2(30);
|
||||
// *b 执行 B 类的 * 重载函数,返回 A 类的对象
|
||||
(*b2).printA();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// 静态成员函数, 内部只能访问静态成员变量
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
int m;
|
||||
static int x;
|
||||
static void add(int n)
|
||||
{
|
||||
// m = 10; // error, 静态成员函数不能访问非静态成员
|
||||
x += n;
|
||||
cout << "static x = " << x << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int A::x = 20; // 静态变量的初始化
|
||||
|
||||
int main()
|
||||
{
|
||||
A a1;
|
||||
A::add(10); // static x = 30
|
||||
cout << "a1.x = " << a1.x << endl; // a1.x = 30
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// 静态成员变量不占类对象的空间
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
int m;
|
||||
static int x;
|
||||
A(int m)
|
||||
{
|
||||
this->m = m;
|
||||
}
|
||||
};
|
||||
|
||||
// int A::x = 20; // 静态变量初始化
|
||||
|
||||
int main()
|
||||
{
|
||||
A a1(3);
|
||||
cout << "A size " << sizeof(A) << endl; // 同下
|
||||
cout << "a1 size " << sizeof(a1) << endl; // 4 Byte , 为 int m 的大小
|
||||
return 0;
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// 类的单例设计模式
|
||||
// 私有化构造函数和拷贝函数, 提供一个public的静态函数返回类的指针对象, 声明一个静态的类
|
||||
// 的指针对象。
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A // 单例的类: 类的对象运行期间有且只有一个对象
|
||||
{
|
||||
private:
|
||||
int x;
|
||||
A(int x) { this->x = x; }
|
||||
A(const A &other)
|
||||
{
|
||||
x = other.x;
|
||||
}
|
||||
|
||||
public:
|
||||
static A *getInstance(int x = 0)
|
||||
{
|
||||
if (instance == NULL)
|
||||
{
|
||||
instance = new A(x);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
void show()
|
||||
{
|
||||
cout << "x = " << x << endl;
|
||||
}
|
||||
|
||||
public:
|
||||
static A *instance;
|
||||
};
|
||||
|
||||
A *A::instance = NULL; // 定义初始化,在静态全局区
|
||||
|
||||
int main()
|
||||
{
|
||||
A *a1 = A::getInstance(20);
|
||||
a1->show();
|
||||
|
||||
A *a2 = A::getInstance();
|
||||
a2->show();
|
||||
cout << "a1 addr = " << a1 << endl;
|
||||
cout << "a2 addr = " << a2 << endl;
|
||||
|
||||
delete A::instance; // 释放单例对象的空间
|
||||
|
||||
return 0;
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
// 对象的存储
|
||||
// this 指针与链式编程(构造器模式)
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
int a, b, c;
|
||||
|
||||
public:
|
||||
void setA(int a)
|
||||
{
|
||||
this->a = a;
|
||||
}
|
||||
void setB(int b)
|
||||
{
|
||||
this->b = b;
|
||||
}
|
||||
void setC(int c)
|
||||
{
|
||||
this->c = c;
|
||||
}
|
||||
void show()
|
||||
{
|
||||
cout << "a = " << a << ", b = " << b << ", c = " << c << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class ABuilder
|
||||
{
|
||||
private:
|
||||
A *instance;
|
||||
|
||||
public:
|
||||
ABuilder()
|
||||
{
|
||||
instance = new A();
|
||||
}
|
||||
~ABuilder()
|
||||
{
|
||||
if (instance != NULL)
|
||||
{
|
||||
cout << "~ABuilder()" << endl;
|
||||
delete instance;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
ABuilder &a(int a)
|
||||
{
|
||||
instance->setA(a);
|
||||
return *this;
|
||||
}
|
||||
ABuilder &b(int b)
|
||||
{
|
||||
instance->setB(b);
|
||||
return *this;
|
||||
}
|
||||
ABuilder &c(int c)
|
||||
{
|
||||
instance->setC(c);
|
||||
return *this;
|
||||
}
|
||||
A *build()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// 构建器设计模式: 构造产品,需要构造器一步一步的完成构造,最后 build() 出产品
|
||||
ABuilder builder;
|
||||
A *a1 = builder.a(1).b(3).c(8).build();
|
||||
a1->show();
|
||||
return 0;
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// 当const修饰成员函数时,函数内不能修改普通成员变量,但可以修改mutable修饰的成员变量。 当const修饰类对象时,只能读成员变量,不能修改成员变量的值。可以调用const修饰的成员函数,不
|
||||
// 能调用普通成员函数
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
int x;
|
||||
mutable int y;
|
||||
|
||||
public:
|
||||
void setXY(int x, int y) const
|
||||
{
|
||||
// this->x = x; // error
|
||||
this->y = y;
|
||||
}
|
||||
void show()
|
||||
{
|
||||
cout << x << ", " << y << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
A a1;
|
||||
a1.setXY(1, 2); // const 函数,内部不修改非 mutable 的成员变量
|
||||
a1.show();
|
||||
|
||||
// const A a2; // 报错,const 变量必须存在初始值(右值)
|
||||
const A a2 = A();
|
||||
a2.setXY(0, 30); // const 对象可以访问 const 的成员函数
|
||||
// a2.show(); // const 对象不能访问非 const 成员函数
|
||||
return 0;
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// 友元
|
||||
// 全局友元函数
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class B
|
||||
{
|
||||
// 声明全局函数的友元
|
||||
friend void show(B &b); // 将全局的 show() 函数设置为当前类的友元函数
|
||||
|
||||
private:
|
||||
int x;
|
||||
|
||||
public:
|
||||
B(int x) : x(x) {}
|
||||
void show()
|
||||
{
|
||||
cout << "成员函数 x = " << x << endl;
|
||||
}
|
||||
};
|
||||
|
||||
// 全局的友元函数
|
||||
void show(B &b)
|
||||
{
|
||||
// b 的私有成员
|
||||
cout << "全局友元函数 b.x = " << b.x << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
B b(100);
|
||||
b.show(); // 成员函数 x = 100
|
||||
show(b); // 全局友元函数 b.x = 100
|
||||
return 0;
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
// 友元
|
||||
// 友元的类成员函数
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class B;
|
||||
|
||||
class C
|
||||
{
|
||||
public:
|
||||
// 在此函数内,要访问 B 类中的所有成员,将此函数在 B 类中声明友元
|
||||
// 先声明,不能实现
|
||||
void showB(B &b);
|
||||
};
|
||||
|
||||
class B
|
||||
{
|
||||
// 声明友元的成员函数
|
||||
friend void C::showB(B &b);
|
||||
|
||||
private:
|
||||
int x;
|
||||
|
||||
public:
|
||||
B(int x) : x(x) {}
|
||||
void show()
|
||||
{
|
||||
cout << "成员函数 x = " << x << endl;
|
||||
}
|
||||
};
|
||||
|
||||
// 定义或实现友元的成员函数
|
||||
void C::showB(B &b)
|
||||
{
|
||||
cout << "友元的成员函数 b.x = " << b.x << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
B b(100);
|
||||
b.show();
|
||||
C c;
|
||||
c.showB(b);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// 友元类
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class B;
|
||||
|
||||
class C
|
||||
{
|
||||
public:
|
||||
void showB(B &b);
|
||||
};
|
||||
|
||||
class B
|
||||
{
|
||||
friend class C;
|
||||
|
||||
private:
|
||||
int x;
|
||||
|
||||
public:
|
||||
B(int x) : x(x) {}
|
||||
void show()
|
||||
{
|
||||
cout << "成员函数 x = " << x << endl;
|
||||
}
|
||||
};
|
||||
|
||||
void C::showB(B &b)
|
||||
{
|
||||
cout << "友元类 b.x = " << b.x << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
B b(100);
|
||||
b.show();
|
||||
C c;
|
||||
c.showB(b);
|
||||
return 0;
|
||||
}
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 声明遥控器类
|
||||
class Remote;
|
||||
|
||||
// 定义电视类
|
||||
class Television
|
||||
{
|
||||
friend class Remote;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
On, // 电视开关状态
|
||||
Off
|
||||
};
|
||||
enum
|
||||
{
|
||||
minVol,
|
||||
maxVol = 100 // 音量从 0 到 100
|
||||
};
|
||||
enum
|
||||
{
|
||||
minChannel = 1,
|
||||
maxChannel = 255 // 频道范围 1 到 255
|
||||
};
|
||||
|
||||
Television()
|
||||
{
|
||||
mStatus = Off; // 状态
|
||||
mVolume = minVol; // 声音
|
||||
mChannel = minChannel; // 频道
|
||||
}
|
||||
|
||||
public:
|
||||
void power() // 开关机
|
||||
{
|
||||
this->mStatus = (this->mStatus == On ? Off : On);
|
||||
}
|
||||
|
||||
void VolumeUp() // 调高音量
|
||||
{
|
||||
if (this->mVolume >= maxVol)
|
||||
return;
|
||||
this->mVolume++;
|
||||
}
|
||||
|
||||
void VolumeDown() // 调低音量
|
||||
{
|
||||
if (this->mVolume <= minVol)
|
||||
return;
|
||||
this->mVolume--;
|
||||
}
|
||||
|
||||
void ChannelUp() // 向上更换电视频道
|
||||
{
|
||||
if (this->mChannel >= maxChannel)
|
||||
return;
|
||||
this->mChannel++;
|
||||
}
|
||||
|
||||
void ChannelDown() // 向下更换电视频道
|
||||
{
|
||||
if (this->mChannel <= minChannel)
|
||||
return;
|
||||
this->mChannel--;
|
||||
}
|
||||
|
||||
void ShowTeleState() // 展示当前电视状态信息
|
||||
{
|
||||
cout << "开机状态: " << (mStatus == On ? "已开机" : "已关机") << endl;
|
||||
if (mStatus == On)
|
||||
{
|
||||
cout << "当前音量: " << mVolume << endl;
|
||||
cout << "当前频道: " << mChannel << endl;
|
||||
}
|
||||
cout << "----------------------" << endl;
|
||||
}
|
||||
|
||||
private:
|
||||
int mStatus; // 电视状态
|
||||
int mVolume; // 声音
|
||||
int mChannel; // 频道
|
||||
};
|
||||
|
||||
// 定义遥控器
|
||||
class Remote
|
||||
{
|
||||
public:
|
||||
Remote(Television *tv) // 构造函数
|
||||
{
|
||||
pTV = tv;
|
||||
}
|
||||
|
||||
public:
|
||||
void power() // 开关机
|
||||
{
|
||||
pTV->power();
|
||||
}
|
||||
|
||||
void VolumeUp() // 调高音量
|
||||
{
|
||||
pTV->VolumeUp();
|
||||
}
|
||||
|
||||
void VolumeDown() // 调低音量
|
||||
{
|
||||
pTV->VolumeDown();
|
||||
}
|
||||
|
||||
void ChannelUp() // 向上更换电视频道
|
||||
{
|
||||
pTV->ChannelUp();
|
||||
}
|
||||
|
||||
void ChannelDown() // 向下更换电视频道
|
||||
{
|
||||
pTV->ChannelDown();
|
||||
}
|
||||
|
||||
// 设置频道,遥控器新增功能
|
||||
void SetChannel(int channel)
|
||||
{
|
||||
if (channel < Television::minChannel || channel > Television::maxChannel)
|
||||
return;
|
||||
pTV->mChannel = channel;
|
||||
}
|
||||
|
||||
void ShowTeleState() // 展示当前电视状态信息
|
||||
{
|
||||
pTV->ShowTeleState();
|
||||
}
|
||||
|
||||
private:
|
||||
Television *pTV;
|
||||
};
|
||||
|
||||
// 直接操作电视
|
||||
void test01()
|
||||
{
|
||||
Television tv;
|
||||
tv.ShowTeleState();
|
||||
tv.power(); // 开机
|
||||
tv.VolumeUp(); // 音量 +1
|
||||
tv.VolumeUp();
|
||||
tv.VolumeUp();
|
||||
tv.VolumeUp();
|
||||
tv.ChannelUp(); // 频道 +1
|
||||
tv.ChannelUp();
|
||||
tv.ShowTeleState();
|
||||
}
|
||||
|
||||
// 通过遥控器操作电视
|
||||
void test02()
|
||||
{
|
||||
// 创建电视
|
||||
Television tv;
|
||||
|
||||
// 创建遥控器
|
||||
Remote rmt(&tv);
|
||||
|
||||
rmt.ShowTeleState();
|
||||
rmt.power(); // 开机
|
||||
rmt.VolumeUp(); // 音量 +1
|
||||
rmt.VolumeUp();
|
||||
rmt.VolumeUp();
|
||||
rmt.VolumeUp();
|
||||
rmt.ChannelUp(); // 频道 +1
|
||||
rmt.ChannelUp();
|
||||
rmt.SetChannel(100);
|
||||
rmt.ShowTeleState();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// test01();
|
||||
test02();
|
||||
return 0;
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
// 运算符重载
|
||||
// + 运算符
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
int x;
|
||||
|
||||
public:
|
||||
explicit A(int x)
|
||||
{
|
||||
this->x = x;
|
||||
}
|
||||
void show()
|
||||
{
|
||||
cout << x << endl;
|
||||
}
|
||||
// + 运算符重载,类成员函数,双目运算符,只需要一个参数
|
||||
A *operator+(A &other);
|
||||
};
|
||||
|
||||
A *A::operator+(A &other)
|
||||
{
|
||||
A *tmp = new A(this->x + other.x);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
A a1(5), a2(6);
|
||||
a1.show();
|
||||
A *a3 = a1 + a2;
|
||||
a3->show();
|
||||
delete a3;
|
||||
return 0;
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
// 运算符重载
|
||||
// ++、-- 运算符
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
int x;
|
||||
|
||||
public:
|
||||
explicit A(int x)
|
||||
{
|
||||
this->x = x;
|
||||
}
|
||||
void show()
|
||||
{
|
||||
cout << x << endl;
|
||||
}
|
||||
// ++ 运算符重载,类成员函数,单目运算符,++ 在前时不要参数,++ 在后需要一个占位参数
|
||||
A &operator++(int);
|
||||
A &operator++();
|
||||
A *operator--(int);
|
||||
A *operator--();
|
||||
};
|
||||
|
||||
A &A::operator++(int) // ++ 在后需要有占位参数
|
||||
{
|
||||
this->x++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
A &A::operator++()
|
||||
{
|
||||
++this->x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
A *A::operator--(int)
|
||||
{
|
||||
A *tmp = new A(this->x--);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
A *A::operator--()
|
||||
{
|
||||
A *tmp = new A(--this->x);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
A a1(5);
|
||||
a1.show();
|
||||
a1++;
|
||||
a1.show();
|
||||
++a1;
|
||||
a1--;
|
||||
a1.show();
|
||||
--a1;
|
||||
a1.show();
|
||||
|
||||
A a2(8);
|
||||
a2--;
|
||||
a2--;
|
||||
a2++;
|
||||
++a2;
|
||||
--a2;
|
||||
a2.show();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// 如下程序运行的结果是什么 ? 是否存在错误,如果有错请指出并分析原因。
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Abc
|
||||
{
|
||||
private:
|
||||
int rN;
|
||||
|
||||
public:
|
||||
Abc(int x) : rN(x) {}
|
||||
static void print()
|
||||
{
|
||||
Abc abc(20);
|
||||
cout << abc.rN << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Abc::print();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
// 设已经有A,B,C,D 4个类的定义,程序中A,B,C,D析构函数调用顺序为( )
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A() { cout << "A()" << endl; }
|
||||
~A()
|
||||
{
|
||||
cout << "~A()" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class B
|
||||
{
|
||||
public:
|
||||
B() { cout << "B()" << endl; }
|
||||
~B()
|
||||
{
|
||||
cout << "~B()" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class C
|
||||
{
|
||||
public:
|
||||
C() { cout << "C()" << endl; }
|
||||
~C()
|
||||
{
|
||||
cout << "~C()" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class D
|
||||
{
|
||||
public:
|
||||
D() { cout << "D()" << endl; }
|
||||
~D()
|
||||
{
|
||||
cout << "~D()" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
C c;
|
||||
|
||||
int main()
|
||||
{
|
||||
A *pa = new A();
|
||||
B b;
|
||||
static D d;
|
||||
delete pa;
|
||||
}
|
||||
|
||||
/*
|
||||
C()
|
||||
A()
|
||||
B()
|
||||
D()
|
||||
~A()
|
||||
~B()
|
||||
~D()
|
||||
~C()
|
||||
*/
|
||||
@@ -0,0 +1,35 @@
|
||||
// 运行以下程序,写出其输出的结果?
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Test
|
||||
{
|
||||
public:
|
||||
Test(int i = 0)
|
||||
{
|
||||
cout << i;
|
||||
}
|
||||
Test(const Test &x)
|
||||
{
|
||||
cout << 2;
|
||||
}
|
||||
Test &operator=(const Test &x)
|
||||
{
|
||||
cout << 3;
|
||||
return *this;
|
||||
}
|
||||
~Test()
|
||||
{
|
||||
cout << 4;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Test obj1(1), obj2(2);
|
||||
Test obj3 = obj1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 122444 */
|
||||
@@ -0,0 +1,45 @@
|
||||
// 设计Car类,包含color(颜色)、weight(重量) 两个属性和一个带color和weight两个参数的构造函数、以及driver() 驾车、start() 启动、stop() 停车的函数。
|
||||
// 【提示】设计的类,可以在main() 自行测试
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Car
|
||||
{
|
||||
public:
|
||||
Car(const string &color, int weight) : color(color), weight(weight) {}
|
||||
|
||||
public:
|
||||
void driver()
|
||||
{
|
||||
cout << "驾车 " << this->weight << " 车重" << endl;
|
||||
}
|
||||
void start()
|
||||
{
|
||||
cout << "启动 " << this->color << " 颜色的车" << endl;
|
||||
}
|
||||
void stop()
|
||||
{
|
||||
cout << "停车" << endl;
|
||||
}
|
||||
|
||||
private:
|
||||
string color; // 颜色
|
||||
int weight; // 重量
|
||||
};
|
||||
|
||||
void test()
|
||||
{
|
||||
Car car("blue", 1200);
|
||||
car.start();
|
||||
car.driver();
|
||||
car.stop();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
// 继上面的Car类, 设计Person类,并设置Car类为Person类的友元类,使得在Person类的成员函数直接访问 Car对象的所有成员。
|
||||
// 【提示】Person类的构造函数传入 Car类的对象, 增加Person的成员函数用于操作Car类的成员函数或访问Car对象的属性。
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Car
|
||||
{
|
||||
friend class Person;
|
||||
|
||||
public:
|
||||
Car(const string &color, int weight) : color(color), weight(weight) {}
|
||||
|
||||
public:
|
||||
void driver()
|
||||
{
|
||||
cout << "驾车 " << this->weight << " 车重" << endl;
|
||||
}
|
||||
void start()
|
||||
{
|
||||
cout << "启动 " << this->color << " 颜色的车" << endl;
|
||||
}
|
||||
void stop()
|
||||
{
|
||||
cout << "停车" << endl;
|
||||
}
|
||||
|
||||
private:
|
||||
string color; // 颜色
|
||||
int weight; // 重量
|
||||
};
|
||||
|
||||
class Person
|
||||
{
|
||||
// friend class Car;
|
||||
|
||||
public:
|
||||
Person(Car &car) : tcar(car) {}
|
||||
|
||||
public:
|
||||
void setCarColor(const string &color)
|
||||
{
|
||||
// strcpy(tcar.color, color);
|
||||
tcar.color = color;
|
||||
}
|
||||
void setCarWeight(int weight)
|
||||
{
|
||||
tcar.weight = weight;
|
||||
}
|
||||
void show()
|
||||
{
|
||||
cout << "驾驶着一辆" << tcar.color << ", 重" << tcar.weight << "千克的车辆" << endl;
|
||||
}
|
||||
|
||||
private:
|
||||
Car &tcar;
|
||||
};
|
||||
|
||||
void test()
|
||||
{
|
||||
Car car("红色", 1000);
|
||||
Person person(car);
|
||||
person.setCarColor("蓝色");
|
||||
person.setCarWeight(1230);
|
||||
|
||||
car.start();
|
||||
car.driver();
|
||||
car.stop();
|
||||
|
||||
person.show();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// 自定义ArrayList类,实现线性列表(类似数组)结构的数据元素操作。操作方法:
|
||||
// 1. add(int) 添加int整型的数据元素
|
||||
// 2. remove(int) 删除数据元素
|
||||
// 3. int get(int index) 获取指定位置的元素
|
||||
// 4. void print() 打印列表中所有元素
|
||||
// 5. int size() 返回列表的当前大小
|
||||
// 6. void sort(bool reversed = false) 元素排序,reversed为true时,表示从大小到小,反之,表示从小到到。
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class ArrayList
|
||||
{
|
||||
private:
|
||||
vector<int> elements; // 动态数组元素
|
||||
|
||||
public:
|
||||
void add(int value) // 添加 int 整型的数据元素
|
||||
{
|
||||
elements.push_back(value);
|
||||
}
|
||||
void remove(int index) // 删除数据元素
|
||||
{
|
||||
int size = elements.size();
|
||||
if (index >= 0 && index < size)
|
||||
elements.erase(elements.begin() + index);
|
||||
}
|
||||
int get(int index) // 获取指定位置的元素
|
||||
{
|
||||
int size = elements.size();
|
||||
if (index >= 0 && index < size)
|
||||
return elements[index];
|
||||
return -1; // 返回无效索引,表示未找到元素
|
||||
}
|
||||
void print() // 打印列表中的所有元素
|
||||
{
|
||||
for (int i = 0; i < elements.size(); i++)
|
||||
cout << elements[i] << " ";
|
||||
}
|
||||
int size() // 返回列表的当前大小
|
||||
{
|
||||
return elements.size();
|
||||
}
|
||||
void sort(bool reversed = false) // 默认从小到大排序,当reversed 为 true 时,从大到小排序
|
||||
{
|
||||
if (reversed == true)
|
||||
std::sort(elements.rbegin(), elements.rend());
|
||||
else
|
||||
std::sort(elements.begin(), elements.end());
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
ArrayList list;
|
||||
|
||||
list.add(5);
|
||||
list.add(2);
|
||||
list.add(8);
|
||||
list.add(9);
|
||||
list.add(13);
|
||||
|
||||
cout << "原始列表: ";
|
||||
list.print();
|
||||
cout << endl;
|
||||
|
||||
cout << "列表大小为: " << list.size() << endl;
|
||||
|
||||
cout << "删除第二位的元素后显示为: ";
|
||||
list.remove(2);
|
||||
list.print();
|
||||
cout << endl;
|
||||
|
||||
cout << "此时第二位的元素为: " << list.get(2) << endl;
|
||||
|
||||
cout << "从大到小排序后列表为: ";
|
||||
list.sort(true);
|
||||
list.print();
|
||||
cout << endl;
|
||||
|
||||
cout << "从小到大排序后列表为: ";
|
||||
list.sort();
|
||||
list.print();
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
// 自定义ArrayList类,实现线性列表(类似数组)结构的数据元素操作。操作方法:
|
||||
// 1. add(int) 添加int整型的数据元素
|
||||
// 2. remove(int) 删除数据元素
|
||||
// 3. int get(int index) 获取指定位置的元素
|
||||
// 4. void print() 打印列表中所有元素
|
||||
// 5. int size() 返回列表的当前大小
|
||||
// 6. void sort(bool reversed = false) 元素排序,reversed为true时,表示从大小到小,反之,表示从小到到。
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class ArrayList
|
||||
{
|
||||
private:
|
||||
int *elements; // 存储元素的数组
|
||||
int capacity; // 数组的容量
|
||||
int count; // 当前元素的数量
|
||||
public:
|
||||
ArrayList() : capacity(10), elements(new int[capacity]), count(0) {}
|
||||
~ArrayList()
|
||||
{
|
||||
delete[] elements;
|
||||
}
|
||||
|
||||
public:
|
||||
void add(int value);
|
||||
void remove(int index);
|
||||
int get(int index);
|
||||
void print();
|
||||
int size();
|
||||
void sort(bool reversed = false);
|
||||
};
|
||||
|
||||
void ArrayList::add(int value)
|
||||
{
|
||||
if (count == capacity)
|
||||
{
|
||||
// 如果数组已满,扩容为原来的两倍
|
||||
int newCapacity = capacity * 2;
|
||||
int *newElements = new int[newCapacity];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
newElements[i] == elements[i];
|
||||
}
|
||||
delete[] elements;
|
||||
elements = newElements;
|
||||
capacity = newCapacity;
|
||||
}
|
||||
elements[count] = value;
|
||||
count++;
|
||||
}
|
||||
|
||||
void ArrayList::remove(int index)
|
||||
{
|
||||
if (index >= 0 && index < count)
|
||||
{
|
||||
for (int i = index; i < count - 1; i++)
|
||||
{
|
||||
// index 后面的元素全部前移一位
|
||||
elements[i] = elements[i + 1];
|
||||
}
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
int ArrayList::get(int index)
|
||||
{
|
||||
if (index >= 0 && index < count)
|
||||
return elements[index];
|
||||
return -1; // 返回无效值,表示未找到内容
|
||||
}
|
||||
|
||||
void ArrayList::print()
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
cout << elements[i] << " ";
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int ArrayList::size()
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
void ArrayList::sort(bool reversed)
|
||||
{
|
||||
for (int i = 0; i < count - 1; i++)
|
||||
{
|
||||
for (int j = 0; j < count - i - 1; j++)
|
||||
{
|
||||
if (reversed) // 等价于 reversed == true
|
||||
{
|
||||
if (elements[j] < elements[j + 1])
|
||||
{
|
||||
int tmp = elements[j];
|
||||
elements[j] = elements[j + 1];
|
||||
elements[j + 1] = tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (elements[j] > elements[j + 1])
|
||||
{
|
||||
int tmp = elements[j];
|
||||
elements[j] = elements[j + 1];
|
||||
elements[j + 1] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
ArrayList list;
|
||||
|
||||
list.add(5);
|
||||
list.add(8);
|
||||
list.add(7);
|
||||
list.add(2);
|
||||
list.add(1);
|
||||
|
||||
cout << "原始列表: ";
|
||||
list.print();
|
||||
cout << endl;
|
||||
|
||||
cout << "列表大小为: " << list.size() << endl;
|
||||
|
||||
cout << "删除第二位的元素后显示为: ";
|
||||
list.remove(2);
|
||||
list.print();
|
||||
cout << endl;
|
||||
|
||||
cout << "此时第二位的元素为: " << list.get(2) << endl;
|
||||
|
||||
cout << "从大到小排序后列表为: ";
|
||||
list.sort(true);
|
||||
list.print();
|
||||
cout << endl;
|
||||
|
||||
cout << "从小到大排序后列表为: ";
|
||||
list.sort();
|
||||
list.print();
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
// = 赋值重载
|
||||
// 注意 = 重载时,可能会调用类本身的拷贝构造函数。如果左值是没有创建的对象时,
|
||||
// 会调用类的拷贝构造函数
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
int x;
|
||||
|
||||
public:
|
||||
A(int x) : x(x)
|
||||
{
|
||||
cout << "A(int x)" << endl;
|
||||
}
|
||||
A(const A &obj)
|
||||
{
|
||||
cout << "A(A &obj)" << endl;
|
||||
this->x = obj.x;
|
||||
}
|
||||
A &operator=(const A &other)
|
||||
{
|
||||
cout << "A &operator=(A&other)" << endl;
|
||||
this->x = other.x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
void show()
|
||||
{
|
||||
cout << "x = " << x << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
A a1(100), a2(200);
|
||||
A a4 = 300; // A(300)
|
||||
a4 = 400; // operator=()
|
||||
|
||||
A a3 = a1; // A(a1)
|
||||
a3.show();
|
||||
|
||||
a3 = a2; // operator=() 调用赋值重载函数
|
||||
a3.show();
|
||||
|
||||
a3 = a4;
|
||||
a3.show();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
// () 函数调用重载
|
||||
// 当类对象作为函数调用时,会执行 operator()(参数列表) 函数
|
||||
//
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
int x, y;
|
||||
|
||||
public:
|
||||
A(int x, int y) : x(x), y(y) {}
|
||||
|
||||
public:
|
||||
void operator()(int a, int b)
|
||||
{
|
||||
this->x += a;
|
||||
this->y += b;
|
||||
show();
|
||||
}
|
||||
|
||||
void show()
|
||||
{
|
||||
cout << x << ", " << y << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
A a1(10, 9);
|
||||
a1.show();
|
||||
|
||||
a1(2, 3); // 类对象作为函数使用,实现 2+x,3+y
|
||||
// a1.show();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
# 定义路径变量
|
||||
SRC_DIR = ./
|
||||
OBJ_DIR = ./
|
||||
BIN_DIR = ./
|
||||
|
||||
# 定义编译器
|
||||
CC = g++
|
||||
STD = -std=c++11
|
||||
# 定义目标文件
|
||||
TARGET = $(BIN_DIR)/a.out
|
||||
# 定义源文件
|
||||
SRCS = $(wildcard $(SRC_DIR)/*.cpp)
|
||||
# OBJS = $(OBJ_DIR)/lrc.o $(OBJ_DIR)/console.o $(OBJ_DIR)/start_mplayer.o $(OBJ_DIR)/time_delay.o $(OBJ_DIR)/main.o
|
||||
OBJS = $(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(SRCS))
|
||||
|
||||
# 编译规则
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
|
||||
$(CC) -c $< -o $@ $(STD)
|
||||
|
||||
# 链接规则
|
||||
$(TARGET): $(OBJS)
|
||||
$(CC) $^ -o $@ $(STD)
|
||||
|
||||
# 默认构建目标
|
||||
all: $(TARGET)
|
||||
|
||||
# 创建目录
|
||||
$(shell mkdir -p $(OBJ_DIR) $(BIN_DIR))
|
||||
|
||||
# 运行测试
|
||||
run: $(TARGET)
|
||||
$(TARGET)
|
||||
|
||||
# 清理规则
|
||||
clean:
|
||||
rm -rf $(OBJ_DIR)/*.o $(TARGET)
|
||||
|
||||
# 伪目标
|
||||
.PHONY: all clean
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "mystring.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
MyString s1("disen");
|
||||
cout << s1 + ",lucy" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
#include "mystring.h"
|
||||
using namespace std;
|
||||
|
||||
ostream &operator<<(ostream &cout, const MyString &str)
|
||||
{
|
||||
cout << str.mStr; // 输出字符串 mStr
|
||||
return cout; // 返回 cout 输出流对象
|
||||
}
|
||||
istream &operator<<(istream &cin, MyString &str)
|
||||
{
|
||||
cin >> str.mStr; // 输入字符串 mStr
|
||||
return cin; // 返回 cin 输入流对象
|
||||
}
|
||||
|
||||
MyString::MyString(const char *str)
|
||||
{
|
||||
mSize = strlen(str); // 计算字符串长度
|
||||
mStr = new char[mSize + 1]; // 为 '\0' 留一个位置
|
||||
strcpy(mStr, str); // 拷贝字符串
|
||||
}
|
||||
|
||||
MyString::MyString(const MyString &str)
|
||||
{
|
||||
mSize = str.mSize; // 拷贝字符串长度
|
||||
char *p = new char[mSize + 1]; // 为 '\0' 留一个位置
|
||||
strcpy(p, str.mStr); // 拷贝字符串
|
||||
delete[] this->mStr; // 删除之前的空间
|
||||
this->mStr = p; // 指向新的空间
|
||||
}
|
||||
|
||||
MyString::~MyString()
|
||||
{
|
||||
delete[] mStr; // 释放空间
|
||||
}
|
||||
|
||||
// 字符串拼接
|
||||
MyString &MyString::operator+(MyString &other)
|
||||
{
|
||||
mSize += other.mSize; // 计算新的字符串长度, 用原有长度加上 other 的长度
|
||||
char *p = new char[mSize + 1]; // 为 '\0' 留一个位置
|
||||
strcpy(p, mStr); // 拷贝 mStr
|
||||
strcat(p, other.mStr); // 拼接 other.mStr
|
||||
delete[] this->mStr; // 删除之前的空间
|
||||
this->mStr = p; // 指向新的空间
|
||||
}
|
||||
|
||||
MyString &MyString::operator+(const char *other)
|
||||
{
|
||||
mSize += strlen(other); // 计算新的字符串长度, 用原有长度加上 other 的长度
|
||||
char *p = new char[mSize + 1]; // 为 '\0' 留一个位置
|
||||
strcpy(p, mStr); // 拷贝 mStr
|
||||
strcat(p, other); // 拼接 other
|
||||
delete[] this->mStr; // 删除之前的空间
|
||||
this->mStr = p; // 指向新的空间
|
||||
}
|
||||
|
||||
// 字符串赋值
|
||||
MyString &MyString::operator=(MyString &other)
|
||||
{
|
||||
mSize = other.mSize; // 拷贝字符串长度
|
||||
char *p = new char[mSize + 1]; // 为 '\0' 留一个位置
|
||||
strcpy(p, other.mStr); // 拷贝字符串
|
||||
delete[] mStr; // 删除之前的空间
|
||||
mStr = p; // 指向新的空间
|
||||
}
|
||||
|
||||
MyString &MyString::operator=(const char *other)
|
||||
{
|
||||
mSize = strlen(other); // 拷贝字符串长度
|
||||
char *p = new char[mSize + 1]; // 为 '\0' 留一个位置
|
||||
strcpy(p, other); // 拷贝字符串
|
||||
delete[] mStr; // 删除之前的空间
|
||||
mStr = p; // 指向新的空间
|
||||
}
|
||||
|
||||
// 字符串比较
|
||||
MyString &operator==(MyString &other)
|
||||
{
|
||||
return strcmp(mStr, other.mStr) == 0; // 比较字符串
|
||||
}
|
||||
|
||||
MyString &operator==(const char *other)
|
||||
{
|
||||
return strcmp(mStr, other) == 0; // 比较字符串
|
||||
}
|
||||
|
||||
// 读取字符串中 index 位置的字符
|
||||
char MyString::operator[](int index)
|
||||
{
|
||||
cout << "长度: " << mSize << endl;
|
||||
// index 支持负数, -1 表示倒数第一个字符
|
||||
// index 是负数,计算机存储是补码,如果直接位运算,以补码的方式 & 位运算符
|
||||
// 需要手动取反补码(~), 然后 +1
|
||||
int absIndex = (~index + 1) & 0x7fffffff; // 0x7fffffff 是有符号正整数 int 的最大值
|
||||
// 0x7fffffff = 0111 1111 1111 1111 1111 1111 1111 1111
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef __MYSTRING_H__
|
||||
#define __MYSTRING_H__
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
// 重载: 实现自定义字符串类
|
||||
class MyString
|
||||
{
|
||||
friend ostream &operator<<(ostream &cout, const MyString &str) {}
|
||||
friend istream &operator<<(istream &cout, MyString &str) {}
|
||||
|
||||
public:
|
||||
MyString(const char *str); // 有参构造函数
|
||||
MyString(const MyString &str); // 拷贝构造函数
|
||||
~MyString(); // 析构函数
|
||||
|
||||
public:
|
||||
// 字符串拼接
|
||||
MyString &operator+(MyString &other); // 重载 + 运算符
|
||||
MyString &operator+(const char *other); // 重载 + 运算符
|
||||
|
||||
// 字符串赋值
|
||||
MyString &operator=(MyString &other); // 重载 = 运算符
|
||||
MyString &operator=(const char *other); // 重载 = 运算符
|
||||
|
||||
// 字符串比较
|
||||
MyString &operator==(MyString &other); // 重载 == 运算符
|
||||
MyString &operator==(const char *other); // 重载 == 运算符
|
||||
|
||||
// 读取字符串中 index 位置的字符
|
||||
char operator[](int index); // 重载 [] 运算符
|
||||
|
||||
private:
|
||||
char *mStr; // 字符串
|
||||
int mSize; // 字符串长度
|
||||
};
|
||||
|
||||
ostream &operator<<(ostream &cout, const MyString &str);
|
||||
istream &operator<<(istream &cout, MyString &str);
|
||||
|
||||
#endif
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// 构造函数
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Person
|
||||
{
|
||||
private:
|
||||
string name;
|
||||
int age;
|
||||
|
||||
public:
|
||||
Person(const string &name, int age) : name(name), age(age) {}
|
||||
|
||||
public:
|
||||
void hi()
|
||||
{
|
||||
cout << this->name << ", " << this->age << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class Worker : public Person
|
||||
{
|
||||
private:
|
||||
int salary; // 工资
|
||||
int year; // 工作年限
|
||||
|
||||
public:
|
||||
// 子类的构造函数定义时,可以调用父类的构造函数进行父类成员的初始化
|
||||
// 使用初始化列表实现(调用父类的构造函数,传入对应参数)
|
||||
Worker(const string &name, int age, int salary, int year) : Person(name, age), salary(salary), year(year)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
void hi() // 重写了父类的函数,覆盖了父类的 hi()
|
||||
{
|
||||
// 先调用父类的 hi()
|
||||
Person::hi();
|
||||
cout << salary << ", " << year << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Worker w1 = Worker("liming", 18, 2100, 2);
|
||||
w1.hi();
|
||||
return 0;
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
int a;
|
||||
|
||||
protected:
|
||||
int b;
|
||||
|
||||
private:
|
||||
int c;
|
||||
|
||||
public:
|
||||
A(int a, int b, int c) : a(a), b(b), c(c) {}
|
||||
|
||||
public:
|
||||
void showA()
|
||||
{
|
||||
cout << "A: " << a << ", " << b << ", " << c << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class B : public A
|
||||
{
|
||||
public:
|
||||
B() : A(1, 3, 2) {}
|
||||
|
||||
public:
|
||||
void showB()
|
||||
{
|
||||
showA();
|
||||
// B 类的成员函数内,可以访问父类的 public 、protected 成员
|
||||
// a, b 是父类的 public/protected 的成员变量
|
||||
cout << "B: " << a << ", " << b << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class C : protected B
|
||||
{
|
||||
public:
|
||||
C() : B() {}
|
||||
|
||||
public:
|
||||
void showC()
|
||||
{
|
||||
showA();
|
||||
showB();
|
||||
cout << "C: " << a << ", " << b << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class D : private C
|
||||
{
|
||||
public:
|
||||
D() : C() {}
|
||||
|
||||
public:
|
||||
void showD()
|
||||
{
|
||||
showA();
|
||||
cout << "D: " << a << ", " << b << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class E : public D
|
||||
{
|
||||
public:
|
||||
E() : D() {}
|
||||
|
||||
public:
|
||||
void showE()
|
||||
{
|
||||
showA();
|
||||
// cout << "E: " << a << ", " << b << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// B b1;
|
||||
// b1.showA();
|
||||
// b1.showB();
|
||||
|
||||
// C c1;
|
||||
// c1.showC();
|
||||
|
||||
// D d1;
|
||||
// d1.showD();
|
||||
|
||||
E e1;
|
||||
e1.showD();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
int x;
|
||||
|
||||
private:
|
||||
int y;
|
||||
|
||||
public:
|
||||
A(int x, int y)
|
||||
// A()
|
||||
{
|
||||
cout << "A(int x,int y)" << endl;
|
||||
// cout << "A()" << endl;
|
||||
}
|
||||
~A()
|
||||
{
|
||||
cout << "~A()" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class B : public A
|
||||
{
|
||||
private:
|
||||
int y;
|
||||
|
||||
public:
|
||||
B() : A(1, 2)
|
||||
{
|
||||
cout << "B()" << endl;
|
||||
}
|
||||
~B()
|
||||
{
|
||||
cout << "~B()" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "A size is " << sizeof(A) << endl;
|
||||
cout << "B size is " << sizeof(B) << endl;
|
||||
|
||||
B b1; // A() B() ~B() ~A()
|
||||
|
||||
// A a;
|
||||
|
||||
return 0;
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
// 继承中同名成员的处理方法
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
int x;
|
||||
A(int x) : x(x) {}
|
||||
void show()
|
||||
{
|
||||
cout << "x = " << x << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class B : public A
|
||||
{
|
||||
private:
|
||||
int x;
|
||||
|
||||
public:
|
||||
// B(int x) : A(x)
|
||||
// {
|
||||
// // 就近原则: this->x 是 B 类的,不是父类 A 的
|
||||
// this->x = x + 20;
|
||||
// }
|
||||
B(int x) : A(x), x(x + 20)
|
||||
{
|
||||
}
|
||||
|
||||
void showX()
|
||||
{
|
||||
cout << "x = " << x << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
B b1(10);
|
||||
b1.show(); // 从 A 类继承过来的方法,打印的是 A 类的 x
|
||||
b1.showX(); // B 类自己的,打印自己的 a
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// 编写一个名为 String 的类,表示字符串。重载赋值运算符 = ,使其能够执行字符串的赋值操作。
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class String
|
||||
{
|
||||
private:
|
||||
char *str;
|
||||
|
||||
public:
|
||||
String(const char *s = NULL) // 构造函数: 默认参数为NULL,表示构造一个空字符串
|
||||
{
|
||||
if (s == NULL)
|
||||
str = NULL;
|
||||
|
||||
else
|
||||
{
|
||||
str = new char[strlen(s) + 1];
|
||||
strcpy(str, s);
|
||||
}
|
||||
}
|
||||
|
||||
String(const String &s)
|
||||
{
|
||||
if (s.str == NULL)
|
||||
str = NULL;
|
||||
|
||||
else
|
||||
{
|
||||
str = new char[strlen(s.str) + 1];
|
||||
strcpy(str, s.str);
|
||||
}
|
||||
}
|
||||
|
||||
~String()
|
||||
{
|
||||
if (str != NULL) // 如果str不为空,删除str
|
||||
delete[] str;
|
||||
}
|
||||
|
||||
public:
|
||||
String &operator=(const String &s)
|
||||
{
|
||||
if (str == s.str)
|
||||
return *this;
|
||||
|
||||
if (str != NULL) // 如果str不为空,则先删除str
|
||||
delete[] str; // 删除的目的是为了防止内存泄漏
|
||||
|
||||
if (s.str == NULL) // 如果s.str为空,则str也为空
|
||||
str = NULL;
|
||||
|
||||
else
|
||||
str = new char[strlen(s.str) + 1]; // +1 是为了存放'\0'
|
||||
strcpy(str, s.str);
|
||||
|
||||
return *this; // 返回当前对象的引用
|
||||
}
|
||||
|
||||
void print()
|
||||
{
|
||||
if (str != NULL)
|
||||
cout << str << endl;
|
||||
|
||||
else
|
||||
cout << "NULL" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
String s1("hello");
|
||||
s1.print();
|
||||
String *s2 = new String("world");
|
||||
|
||||
s2->print();
|
||||
s1 = "xi'an";
|
||||
|
||||
s2 = &s1;
|
||||
s2->print();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// 编写一个名为 Date 的类,表示日期。重载相等运算符 == ,使其能够比较两个日期是否相等。
|
||||
// 【提示】类中包含year,
|
||||
// month, day三个变量。
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Date
|
||||
{
|
||||
private:
|
||||
int year, month, day;
|
||||
|
||||
public:
|
||||
Date(int year, int month, int day) : year(year), month(month), day(day) {}
|
||||
Date(const Date &d) : year(d.year), month(d.month), day(d.day) {}
|
||||
~Date() {}
|
||||
|
||||
public:
|
||||
bool operator==(const Date &d)
|
||||
{
|
||||
if (year == d.year && month == d.month && day == d.day)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Date d1(2020, 10, 1);
|
||||
Date d2(2020, 10, 1);
|
||||
Date d3(2020, 10, 2);
|
||||
cout << (d1 == d2) << endl; // 1 表示 true
|
||||
cout << (d1 == d3) << endl; // 0 表示 false
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// 编写一个名为 Matrix 的类,表示矩阵。重载乘法运算符 *,使其能够执行两个矩阵的乘法操作。
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Matrix
|
||||
{
|
||||
private:
|
||||
int row, col;
|
||||
int **matrix;
|
||||
|
||||
public:
|
||||
Matrix(int row, int col) : row(row), col(col)
|
||||
{
|
||||
matrix = new int *[row];
|
||||
for (int i = 0; i < row; i++)
|
||||
matrix[i] = new int[col];
|
||||
}
|
||||
|
||||
~Matrix()
|
||||
{
|
||||
for (int i = 0; i < row; i++)
|
||||
delete[] matrix[i];
|
||||
delete[] matrix;
|
||||
}
|
||||
|
||||
public:
|
||||
Matrix operator*(const Matrix &m)
|
||||
{
|
||||
Matrix result(row, m.col);
|
||||
for (int i = 0; i < row; i++)
|
||||
for (int j = 0; j < m.col; j++)
|
||||
for (int k = 0; k < col; k++)
|
||||
result.matrix[i][j] += matrix[i][k] * m.matrix[k][j];
|
||||
return result;
|
||||
}
|
||||
|
||||
friend ostream &operator<<(ostream &out, const Matrix &m)
|
||||
{
|
||||
for (int i = 0; i < m.row; i++)
|
||||
{
|
||||
for (int j = 0; j < m.col; j++)
|
||||
out << m.matrix[i][j] << " ";
|
||||
out << endl;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
friend istream &operator>>(istream &in, Matrix &m)
|
||||
{
|
||||
for (int i = 0; i < m.row; i++)
|
||||
for (int j = 0; j < m.col; j++)
|
||||
in >> m.matrix[i][j];
|
||||
return in;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// 编写一个名为 Complex 的类,表示复数。重载加法运算符 + ,使其能够执行两个复数的加法操作。
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Complex
|
||||
{
|
||||
private:
|
||||
double real, imag; // 实部和虚部
|
||||
|
||||
public:
|
||||
Complex(double real, double imag) : real(real), imag(imag) {}
|
||||
Complex(const Complex &other) : real(other.real), imag(other.imag) {}
|
||||
~Complex() {}
|
||||
|
||||
public:
|
||||
Complex operator+(const Complex &other)
|
||||
{
|
||||
return Complex(real + other.real, imag + other.imag);
|
||||
}
|
||||
void show()
|
||||
{
|
||||
cout << real << " + " << imag << "i" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Complex c1(1, 2);
|
||||
Complex c2(3, 4);
|
||||
Complex c3 = c1 + c2;
|
||||
c3.show(); // 4 + 6i
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// 假设有三个类,Animal(动物),Mammal(哺乳动物)和 Dog(狗)。Animal 类具有一个成员函数 eat() ,用于输出动物吃的食物。Mammal 类继承自 Animal 类,并添加了一个成员函数 giveBirth() ,用于输出哺乳动物的生育方式。Dog 类继承自 Mammal 类,并添加了一个成员函数 bark() ,用于输出狗的叫声。请在给定的类定义中完成代码,并实现相应的成员函数。
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Animal
|
||||
{
|
||||
public:
|
||||
void eat()
|
||||
{
|
||||
cout << "Animal eat" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class Mammal : public Animal
|
||||
{
|
||||
public:
|
||||
void giveBirth()
|
||||
{
|
||||
cout << "Mammal give birth" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class Dog : public Mammal
|
||||
{
|
||||
public:
|
||||
void bark()
|
||||
{
|
||||
cout << "Dog bark" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Dog dog;
|
||||
dog.eat(); // Animal eat
|
||||
dog.giveBirth(); // Mammal give birth
|
||||
dog.bark(); // Dog bark
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// 编写一个名为 MatrixArray 的类,表示矩阵数组。重载乘法运算符 *,使其能够执行两个矩阵积操作。重载[] 运算符,实现返回某一个行的一维数组并对数组进行设置值或访问值。
|
||||
// 【提示】构造函数提供行数与列数的参数,初始值为0。
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class MatrixArray
|
||||
{
|
||||
private:
|
||||
int row, col;
|
||||
int **matrix;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// 假设有两个类,Shape(形状)和 Rectangle(矩形)。Shape 类具有一个成员函数 getArea() ,用于计算形状的面积。Rectangle 类继承自 Shape 类,并添加了两个成员变量 width(宽度)和 height(高度)。请在给定的类定义中完成代码,并实现 Rectangle 类的 getArea() 函数来计算矩形的面积。
|
||||
// 【提示】Shape的类设计如下,表示为抽象类(getArea() 是纯虚函数):
|
||||
// class Shape
|
||||
// {
|
||||
// public:
|
||||
// virtual double getArea() const = 0;
|
||||
// };
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Shape
|
||||
{
|
||||
public:
|
||||
virtual double getArea() const = 0;
|
||||
};
|
||||
|
||||
class Rectangle : public Shape
|
||||
{
|
||||
private:
|
||||
double width, height;
|
||||
|
||||
public:
|
||||
Rectangle(double width, double height) : width(width), height(height) {}
|
||||
~Rectangle() {}
|
||||
|
||||
public:
|
||||
double getArea() const // 重写父类的纯虚函数,const 可以保证不会修改成员变量的值
|
||||
{
|
||||
return width * height;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Shape *shape = new Rectangle(3, 4);
|
||||
cout << shape->getArea() << endl; // 12
|
||||
return 0;
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
// 多继承(同属一个超级父类)产生的问题
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
int x;
|
||||
};
|
||||
|
||||
class B : virtual public A
|
||||
{
|
||||
public:
|
||||
B()
|
||||
{
|
||||
x = 50;
|
||||
}
|
||||
};
|
||||
|
||||
class C : virtual public A
|
||||
{
|
||||
public:
|
||||
C()
|
||||
{
|
||||
x = 100;
|
||||
}
|
||||
};
|
||||
|
||||
class D : public C, public B
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
D d1;
|
||||
cout << d1.x << endl;
|
||||
d1.x = 0; // x 是从 B 来的,还是从 C 来的? C ,使用就近原则
|
||||
cout << d1.x << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
// 初尝多态
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 抽象类:
|
||||
// 至少有一个纯虚函数的类
|
||||
// 抽象类不能实现对象
|
||||
class AbstractCaculator // 定义计算器
|
||||
{
|
||||
protected: // 使用保护权限(目的是使子类可以访问,而其他类不可访问)
|
||||
int a, b;
|
||||
|
||||
public:
|
||||
void setA(int a) { this->a = a; }
|
||||
void setB(int b) { this->b = b; }
|
||||
|
||||
public:
|
||||
// 扩展功能,让子类去实现
|
||||
virtual int getResult() = 0; // 纯虚函数,声明函数并赋值为 0
|
||||
};
|
||||
|
||||
class AddCa : public AbstractCaculator
|
||||
{
|
||||
// 必须要去实现纯虚函数
|
||||
int getResult()
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
};
|
||||
|
||||
class SubCa : public AbstractCaculator
|
||||
{
|
||||
// 必须要去实现纯虚函数
|
||||
int getResult()
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
};
|
||||
|
||||
// 多态的体现:
|
||||
// 1) 定义函数时,形参的类型为父类对象的指针
|
||||
// 2) 调用函数时,实参的类型为子类对象的指针
|
||||
int Result(AbstractCaculator *caculator, int a, int b)
|
||||
{
|
||||
caculator->setA(a);
|
||||
caculator->setB(b);
|
||||
return caculator->getResult();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// 抽象类型不能去定义对象
|
||||
// error: cannot declare variable ‘a1’ to be of abstract type ‘AbstractCaculator’
|
||||
// AbstractCaculator a1;
|
||||
|
||||
AddCa *a2 = new AddCa;
|
||||
cout << Result(a2, 10, 20) << endl;
|
||||
cout << Result(new SubCa, 10, 20) << endl; // new SubCa 返回的是一个临时对象,不需要 delete
|
||||
delete a2;
|
||||
// delete new SubCa; // error: cannot delete expression of type ‘SubCa’
|
||||
|
||||
return 0;
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
// 向上类型转换
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Printer
|
||||
{
|
||||
public:
|
||||
void open()
|
||||
{
|
||||
cout << "打印机正在开机..." << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class DellPrinter : public Printer
|
||||
{
|
||||
void open()
|
||||
{
|
||||
cout << "Dell打印机..." << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class HuaweiPrinter : public Printer
|
||||
{
|
||||
void open()
|
||||
{
|
||||
cout << "Huawei打印机..." << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
DellPrinter dellprinter;
|
||||
// 多态: 通过父类的引用或指针调用子类对象的成员
|
||||
// 子类对象自动向上转换位父类的类型
|
||||
Printer &printer = dellprinter;
|
||||
printer.open(); // 输出: 打印机正在开机...
|
||||
return 0;
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// 将父类的函数改为虚函数
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
clacc Printer
|
||||
{
|
||||
public:
|
||||
virtual void open()
|
||||
{
|
||||
cout << ""
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Animal
|
||||
{
|
||||
protected:
|
||||
string name;
|
||||
float price;
|
||||
|
||||
public:
|
||||
Animal(const string &name, float price)
|
||||
{
|
||||
this->name = name;
|
||||
this->price = price;
|
||||
}
|
||||
virtual void buy(); // 类内声明的虚函数
|
||||
};
|
||||
|
||||
// 类外实现类中的虚函数
|
||||
void Animal::buy()
|
||||
{
|
||||
cout << "小宠物 " << name << " 卖了 " << price << endl;
|
||||
}
|
||||
|
||||
class Dog : public Animal
|
||||
{
|
||||
private:
|
||||
int age;
|
||||
|
||||
public:
|
||||
Dog(string name, float price, int age) : Animal(name, price), age(age)
|
||||
{
|
||||
}
|
||||
virtual void buy() // 重写父类的虚函数
|
||||
{
|
||||
cout << age << " 岁小狗 " << name << " 卖了 " << price << endl;
|
||||
}
|
||||
void eat() // 扩展的新功能
|
||||
{
|
||||
cout << name << " 喝酒" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class Cat : public Animal
|
||||
{
|
||||
private:
|
||||
int age;
|
||||
|
||||
public:
|
||||
Cat(string name, float price) : Animal(name, price)
|
||||
{
|
||||
}
|
||||
virtual void buy() // 重写父类的虚函数
|
||||
{
|
||||
cout << "小猫 " << name << " 卖了 " << price << endl;
|
||||
}
|
||||
void eat() // 扩展的新功能
|
||||
{
|
||||
cout << name << " 吃鱼" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class AnimalShop
|
||||
{
|
||||
public:
|
||||
// 多态应用之一
|
||||
void buy(Animal *animal)
|
||||
{
|
||||
cout << "-----动物之家正在出售小宠物-----" << endl;
|
||||
animal->buy();
|
||||
cout << "-----出售结束-----" << endl;
|
||||
|
||||
delete animal; // 释放堆区空间
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
AnimalShop shop;
|
||||
Dog dog("旺财", 1000, 3);
|
||||
// 多态的应用
|
||||
shop.buy(&dog);
|
||||
shop.buy(new Cat("小花", 500));
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// 编写一个模板函数 maxValue,接受两个参数,并返回其中较大的值。
|
||||
// 【提示】T maxVal(T &v1, T &v2)
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
T maxVal(T &v1, T &v2)
|
||||
{
|
||||
return v1 > v2 ? v1 : v2;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int a = 2, b = 5;
|
||||
cout << "更大的值是: " << maxVal(a, b) << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// 编写一个模板函数 maxValueInArray,接受一个数组和数组的大小,并返回数组中的最大值。
|
||||
//【提示】T maxValueInArray(T arr[], int size)
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
T maxValueInArray(T arr[], int size)
|
||||
{
|
||||
T max = arr[0];
|
||||
for (int i = 1; i < size; i++)
|
||||
if (arr[i] > max)
|
||||
max = arr[i];
|
||||
return max;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int arr1[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 0};
|
||||
char arr2[] = {'a', 'c', 'e', 'G', 'I', 'b', 'd', 'f', 'h', 'j'};
|
||||
int size1 = sizeof(arr1) / sizeof(arr1[0]);
|
||||
int size2 = sizeof(arr2) / sizeof(arr2[0]);
|
||||
|
||||
cout << "arr1 的最大值是: " << maxValueInArray(arr1, size1) << endl;
|
||||
cout << "arr2 的最大值是: " << maxValueInArray(arr2, size2) << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// 创建一个基类 Person,其中包含一个纯虚函数 display() ,用于显示人的信息。从 Person 派生出 Student 类和 Teacher 类,分别实现不同类型人的信息显示。
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Person
|
||||
{
|
||||
public:
|
||||
virtual void display() = 0;
|
||||
};
|
||||
|
||||
class Student : public Person
|
||||
{
|
||||
public:
|
||||
// 子类的 virtual 函数可以不写 virtual 关键字
|
||||
virtual void display()
|
||||
{
|
||||
cout << "Student" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class Teacher : public Person
|
||||
{
|
||||
public:
|
||||
virtual void display()
|
||||
{
|
||||
cout << "Teacher" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Person *p = new Student();
|
||||
p->display();
|
||||
p = new Teacher();
|
||||
p->display();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// 创建一个基类 Animal,其中包含一个纯虚函数 move() ,用于描述动物的移动方式。从 Animal 派生出 Bird 类和 Fish 类,分别实现不同类型动物的移动方式。
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Animal
|
||||
{
|
||||
public:
|
||||
virtual void move() = 0;
|
||||
};
|
||||
|
||||
class Bird : public Animal
|
||||
{
|
||||
public:
|
||||
void move()
|
||||
{
|
||||
cout << "Bird" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class Fish : public Animal
|
||||
{
|
||||
public:
|
||||
void move()
|
||||
{
|
||||
cout << "Fish" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Animal *p = new Bird;
|
||||
p->move();
|
||||
p = new Fish;
|
||||
p->move();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// 创建一个基类 Shape,其中包含一个纯虚函数 draw() ,用于绘制形状。从 Shape 派生出 Rectangle 类和 Circle 类,分别实现不同形状的绘制方法
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Shape
|
||||
{
|
||||
public:
|
||||
virtual void draw() = 0;
|
||||
};
|
||||
|
||||
class Rectangle : public Shape
|
||||
{
|
||||
public:
|
||||
void draw()
|
||||
{
|
||||
cout << "Rectangle" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class Circle : public Shape
|
||||
{
|
||||
public:
|
||||
void draw()
|
||||
{
|
||||
cout << "Circle" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Shape *p = new Rectangle;
|
||||
p->draw();
|
||||
p = new Circle;
|
||||
p->draw();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// 创建一个基类 Shape,其中包含一个纯虚函数 perimeter() ,用于计算形状的周长。从 Shape 派生出 Triangle 类和 Square 类,分别实现计算三角形和正方形的周长的函数。
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Shape
|
||||
{
|
||||
public:
|
||||
// 用于计算形状的周长
|
||||
virtual double perimeter() = 0;
|
||||
};
|
||||
|
||||
class Triangle : public Shape
|
||||
{
|
||||
private:
|
||||
double a, b, c;
|
||||
|
||||
public:
|
||||
Triangle(double a, double b, double c) : a(a), b(b), c(c) {}
|
||||
|
||||
public:
|
||||
double perimeter()
|
||||
{
|
||||
return a + b + c;
|
||||
}
|
||||
};
|
||||
|
||||
class Square : public Shape
|
||||
{
|
||||
private:
|
||||
double a;
|
||||
|
||||
public:
|
||||
Square(double a) : a(a) {}
|
||||
|
||||
public:
|
||||
double perimeter()
|
||||
{
|
||||
return 4 * a;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Shape *p = new Triangle(3, 4, 5);
|
||||
|
||||
cout << "三角形的周长是: " << p->perimeter() << endl;
|
||||
|
||||
p = new Square(5);
|
||||
|
||||
cout << "正方形的周长是: " << p->perimeter() << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
// 继第6题, 基于多态方式,定义一个全局函数排序函数,接收Shape类的数组,并按形状的周长进行从大到少排序。
|
||||
// 【提示】全局函数排序函数 void sort(Shape *arr, int size)
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Shape
|
||||
{
|
||||
public:
|
||||
// 用于计算形状的周长
|
||||
virtual double perimeter() = 0;
|
||||
};
|
||||
|
||||
class Triangle : public Shape
|
||||
{
|
||||
private:
|
||||
double a, b, c;
|
||||
|
||||
public:
|
||||
Triangle(double a, double b, double c) : a(a), b(b), c(c) {}
|
||||
|
||||
public:
|
||||
double perimeter()
|
||||
{
|
||||
return a + b + c;
|
||||
}
|
||||
};
|
||||
|
||||
class Square : public Shape
|
||||
{
|
||||
private:
|
||||
double a;
|
||||
|
||||
public:
|
||||
Square(double a) : a(a) {}
|
||||
|
||||
public:
|
||||
double perimeter()
|
||||
{
|
||||
return 4 * a;
|
||||
}
|
||||
};
|
||||
|
||||
void sort(Shape *arr[], int size) // 这里为什么传指针数组?因为 Shape 是抽象类,不能实例化对象,只能通过指针来操作
|
||||
{
|
||||
for (int i = 0; i < size - 1; i++)
|
||||
{
|
||||
for (int j = 0; j < size - i - 1; j++)
|
||||
{
|
||||
// 比较形状的周长
|
||||
if (arr[j]->perimeter() < arr[j + 1]->perimeter())
|
||||
{
|
||||
// 交换位置
|
||||
swap(arr[j], arr[j + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Shape *p = new Triangle(3, 4, 5);
|
||||
Shape *q = new Square(5);
|
||||
Shape *r = new Triangle(6, 8, 10);
|
||||
Shape *s = new Square(10);
|
||||
Shape *t = new Triangle(5, 12, 13);
|
||||
Shape *u = new Square(13);
|
||||
// Shape *arr[6];
|
||||
// arr[0] = p;
|
||||
// arr[1] = q;
|
||||
Shape *arr[] = {p, q, r, s, t, u}; // arr作为一个指针数组,存了6个指向 Shape 类对象的指针
|
||||
int len = sizeof(arr) / sizeof(arr[0]);
|
||||
|
||||
cout << "排序前:" << endl;
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
cout << arr[i]->perimeter() << endl;
|
||||
}
|
||||
|
||||
sort(arr, len);
|
||||
|
||||
cout << "排序后:" << endl;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
cout << arr[i]->perimeter() << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// 函数模版
|
||||
|
||||
/*
|
||||
template <class T>
|
||||
函数返回值 函数名(T &n1, T &n2)
|
||||
{
|
||||
// 函数体
|
||||
}
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
namespace my
|
||||
{
|
||||
// 推荐使用 typename 而不是 class,因为 typename 更通用
|
||||
template <typename T>
|
||||
void swap(T &a, T &b)
|
||||
{
|
||||
a ^= b;
|
||||
b ^= a;
|
||||
a ^= b;
|
||||
}
|
||||
|
||||
// 函数模版重载: 用于不同类型的参数
|
||||
template <typename T1, typename T2>
|
||||
void swap(T1 &a, T2 &b)
|
||||
{
|
||||
a ^= b;
|
||||
b ^= a;
|
||||
a ^= b;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int a = 2, b = 6;
|
||||
cout << a << ", " << b << endl;
|
||||
my::swap(a, b); // 自动推演类型: swap<int>(a, b)
|
||||
cout << a << ", " << b << endl;
|
||||
|
||||
char c = 30;
|
||||
cout << a << ", " << (int)c << endl;
|
||||
my::swap(a, c); // 自动推演类型
|
||||
cout << a << ", " << (int)c << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// 使用函数模版实现对 char 和 int 数组的排序和打印
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void sort(T arr[], int size)
|
||||
{
|
||||
for (int i = 0; i < size - 1; i++)
|
||||
{
|
||||
int min = i;
|
||||
for (int j = i + 1; j < size; j++)
|
||||
{
|
||||
if (arr[min] > arr[j])
|
||||
{
|
||||
min = j;
|
||||
}
|
||||
}
|
||||
if (min != i)
|
||||
{
|
||||
arr[i] ^= arr[min];
|
||||
arr[min] ^= arr[i];
|
||||
arr[i] ^= arr[min];
|
||||
// T temp = arr[i];
|
||||
// arr[i] = arr[min];
|
||||
// arr[min] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void printArr(T arr[], int size)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
cout << arr[i] << " ";
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int arr1[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 0};
|
||||
char arr2[] = {'a', 'c', 'e', 'G', 'I', 'b', 'd', 'f', 'h', 'j'};
|
||||
int size1 = sizeof(arr1) / sizeof(arr1[0]);
|
||||
int size2 = sizeof(arr2) / sizeof(arr2[0]);
|
||||
|
||||
sort(arr1, size1);
|
||||
sort(arr2, size2);
|
||||
|
||||
printArr(arr1, size1);
|
||||
printArr(arr2, size2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// 多态本质:
|
||||
// 父类引用或指针指向子类对象,通过父类指针或引用来(操作子类对象)调用子类中重写的成员函数
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Animal
|
||||
{
|
||||
public:
|
||||
virtual void speak()
|
||||
{
|
||||
cout << "动物在唱歌..." << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class Dog : public Animal
|
||||
{
|
||||
public:
|
||||
void speak()
|
||||
{
|
||||
cout << "狗在唱歌..." << endl;
|
||||
}
|
||||
};
|
||||
|
||||
void DoBusiness(Animal &animal)
|
||||
{
|
||||
animal.speak();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Dog dog;
|
||||
DoBusiness(dog);
|
||||
return 0;
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
T &maxVal(T &a, T &b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
class A
|
||||
{
|
||||
friend A &maxVal<A>(A &a, A &b); // 模板特化的友元函数,用于访问私有成员
|
||||
|
||||
private:
|
||||
int x;
|
||||
|
||||
public:
|
||||
A(int x) : x(x) {}
|
||||
void show()
|
||||
{
|
||||
cout << "x = " << x << endl;
|
||||
}
|
||||
};
|
||||
|
||||
// 具体化函数模版的重载
|
||||
template <>
|
||||
A &maxVal<A>(A &a, A &b) // 模板特化
|
||||
{
|
||||
if (a.x > b.x)
|
||||
return a;
|
||||
return b;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
A a1(20), a2(50);
|
||||
// A &b = maxVal<A>(a1, a2);
|
||||
A &b = maxVal(a1, a2);
|
||||
b.show();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// 模版类与友元
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
class A
|
||||
{
|
||||
// 内部实现的友元函数(全局性的友元函数,类的外部可以直接访问 showIn(x) ,不需要类对象调用 a.showIn())
|
||||
// 接收当前模版类的引用时,可以指定当前模版类的类型
|
||||
friend void showIn(A<T> &a)
|
||||
{
|
||||
cout << a.item << endl;
|
||||
}
|
||||
|
||||
private:
|
||||
T item;
|
||||
|
||||
public:
|
||||
A(T item)
|
||||
{
|
||||
this->item = item;
|
||||
}
|
||||
|
||||
// public:
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
A<int> a(20);
|
||||
showIn(a);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// 模版类与友元
|
||||
// 外部实现的友元函数
|
||||
// 是函数模板时,必须在类定义之前声明。在类中声明友元全局函数时,必须使用<> 空泛型表示此函数是函数模板。
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
class A;
|
||||
template <typename T>
|
||||
void showOut(A<T> &a);
|
||||
|
||||
template <typename T>
|
||||
class A
|
||||
{
|
||||
// 外部实现的友元函数,它有自己的模版类型,不需要指定当前模版类的类型
|
||||
// <>空泛型表示外部是函数模版,模版的泛型同当前类的泛型
|
||||
// 要求: 必须之前先声明此函数为构造函数
|
||||
friend void showOut<>(A<T> &a);
|
||||
|
||||
private:
|
||||
T item;
|
||||
|
||||
public:
|
||||
A(T item)
|
||||
{
|
||||
this->item = item;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void showOut(A<T> &a) // 全局友元函数
|
||||
{
|
||||
cout << "out item is: " << a.item << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
A<int> a(30);
|
||||
showOut(a);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// 友元函数模板
|
||||
/*
|
||||
格式 :
|
||||
template <typename T>
|
||||
friend 返回值类型 函数名(T &参数名);
|
||||
*/
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
class A
|
||||
{
|
||||
// 友元函数模板,声明的友元函数名不需要加<>空泛型
|
||||
template <typename U>
|
||||
friend void show(A<U> &a);
|
||||
|
||||
private:
|
||||
T item;
|
||||
|
||||
public:
|
||||
A(T item)
|
||||
{
|
||||
this->item = item;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U>
|
||||
void show(A<U> &a)
|
||||
{
|
||||
cout << "template friend item is: " << a.item << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
A<int> a(15);
|
||||
show(a);
|
||||
|
||||
A<float> b(15.5);
|
||||
show(b);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
// 类模板的应用
|
||||
// 设计一个数组模板类(MyArray),完成对不同类型元素的管理
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
class MyArray
|
||||
{
|
||||
private:
|
||||
int index; // 当前元素的位置
|
||||
T *arr; // 指向数组的指针
|
||||
int capacity; // 最大容量
|
||||
int size; // 当前容量
|
||||
|
||||
public:
|
||||
MyArray(int capacity)
|
||||
{
|
||||
this->capacity = capacity; // 最大容量
|
||||
this->size = 0; // 当前容量为0
|
||||
this->index = 0; // 当前元素位置为0
|
||||
this->arr = new T[capacity]; // 申请内存
|
||||
}
|
||||
MyArray(const MyArray<T> &other)
|
||||
{
|
||||
this->index = other.index; // 当前元素的位置
|
||||
this->capacity = other.capacity; // 最大容量
|
||||
this->arr = new T[this->capacity]; // 申请内存
|
||||
for (int i = 0; i <= this->capacity; i++)
|
||||
{
|
||||
this->arr[i] = other.arr[i]; // 拷贝数据
|
||||
}
|
||||
this->size = other.size; // 当前容量
|
||||
}
|
||||
~MyArray()
|
||||
{
|
||||
delete[] this->arr; // 释放内存
|
||||
}
|
||||
|
||||
public:
|
||||
T &get(int index)
|
||||
{
|
||||
return arr[index];
|
||||
}
|
||||
T &operator[](int index)
|
||||
{
|
||||
return arr[index];
|
||||
}
|
||||
// & 是为了链式编程
|
||||
MyArray<T> &push(T item)
|
||||
{
|
||||
if (index < capacity)
|
||||
{
|
||||
arr[index++] = item; // 将元素放入数组
|
||||
size++; // 当前容量加1
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
T pop()
|
||||
{
|
||||
if (index > 0)
|
||||
{
|
||||
size--; // 当前容量减1
|
||||
return arr[--index];
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
int getSize()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
MyArray<int> a1 = MyArray<int>(20);
|
||||
a1[0] = 10;
|
||||
a1[1] = 20;
|
||||
MyArray<int> a2 = a1;
|
||||
cout << "a2[0] = " << a2[0] << ", a2[1] = " << a2[1] << endl;
|
||||
|
||||
a1.push(30).push(40).push(50);
|
||||
for (int i = 0; i <= 3; i++)
|
||||
{
|
||||
cout << a1.pop() << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// 类型转换
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int test1()
|
||||
{
|
||||
float f = 97.5;
|
||||
char c = static_cast<char>(f);
|
||||
cout << "c = " << (int)c << endl;
|
||||
}
|
||||
|
||||
int test2()
|
||||
{
|
||||
float f = 97.5;
|
||||
// int *p = &f; // 指针转换不允许跨类型
|
||||
// int *p = static_cast<int *>(&f);
|
||||
// int *p = (int *)&f;
|
||||
// int *p = dynamic_cast<int *>(&f);
|
||||
float *pf = &f;
|
||||
// double *p = const_cast<double *>(pf);
|
||||
int *p = reinterpret_cast<int *>(pf); // 重新解释类型转换,不安全
|
||||
cout << "*p = " << *p << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test2();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// 静态类型转换
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
int x;
|
||||
A(int x) : x(x) {}
|
||||
};
|
||||
|
||||
class B : public A
|
||||
{
|
||||
public:
|
||||
int y;
|
||||
B(int x, int y) : A(x), y(y) {}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
A *a = new A(5);
|
||||
B *b = new B(10, 20);
|
||||
|
||||
A *c = static_cast<A *>(b); // 静态上行转换,子类指针向父类指针转换
|
||||
// cout << "a.x = " << a->x << endl;
|
||||
// cout << "b.x = " << b->x << ", b.y = " << b->y << endl;
|
||||
// cout << "b = " << b << endl;
|
||||
// cout << "c = " << c << endl;
|
||||
// cout << "c.x = " << c->x << endl;
|
||||
|
||||
// B *b2 = static_cast<B *>(a); // 下行转换,父类指针向子类指针转换
|
||||
// B *b2 = (B *)a; // 强制下行转换,不安全
|
||||
// cout << "b2.x = " << b2->x << ", b2.y = " << b2->y << endl;
|
||||
|
||||
delete a;
|
||||
delete b;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// 动态类型转换
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
protected:
|
||||
int x;
|
||||
|
||||
public:
|
||||
A(int x) : x(x) {}
|
||||
void show()
|
||||
{
|
||||
cout << "A x = " << x << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class B : public A
|
||||
{
|
||||
public:
|
||||
B(int x) : A(x) {}
|
||||
void print()
|
||||
{
|
||||
cout << "B print x = " << x << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class C
|
||||
{
|
||||
};
|
||||
|
||||
void test1()
|
||||
{
|
||||
int a = 65;
|
||||
// 动态转化不支持基本数据类型之间的转换
|
||||
// char c = dynamic_cast<char>(a);
|
||||
// char *c = dynamic_cast<char *>(&a);
|
||||
// cout << "c = " << c << endl;
|
||||
}
|
||||
|
||||
void test2()
|
||||
{
|
||||
A a1 = A(10);
|
||||
B b1 = B(20);
|
||||
|
||||
// 上行转换
|
||||
A &a2 = dynamic_cast<A &>(b1);
|
||||
a2.show();
|
||||
// a2.print(); // 不存在 print 成员函数
|
||||
b1.print();
|
||||
|
||||
// 下行转换: 动态转换不支持(安全)
|
||||
// B &b2 = dynamic_cast<B &>(a2);
|
||||
// b2.print();
|
||||
B &b3 = static_cast<B &>(a2);
|
||||
b3.print();
|
||||
}
|
||||
|
||||
// 不相关类型的转换: 不可动态转换
|
||||
void test3()
|
||||
{
|
||||
A *a = new A(20);
|
||||
// C *p = dynamic_cast<C *>(a);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test3();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// const 转换
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void change(const int *p, int value)
|
||||
{
|
||||
int *q = const_cast<int *>(p); // 转换为非 const 指针
|
||||
*q = value;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int a = 10;
|
||||
const int b = 30; // 存储在符号表,在栈中没有空间
|
||||
// 1. 将变量转化为 const 引用变量【可以】
|
||||
const int &a1 = const_cast<const int &>(a);
|
||||
// 2. 将变量地址转化为 const 指针变量【可以】
|
||||
const int *a2 = const_cast<const int *>(&a);
|
||||
|
||||
// 3. 去掉 b 的 const 修饰
|
||||
// b 在取地址时在占中开辟空间,b1 指向空间
|
||||
// int b1 = const_cast<int>(b);【不可以】
|
||||
int &b1 = const_cast<int &>(b);
|
||||
b1 = 100;
|
||||
cout << "b = " << b << endl;
|
||||
cout << "b1 = " << b1 << endl;
|
||||
|
||||
// 4. 去掉 a2 的 const 修饰
|
||||
int *a3 = const_cast<int *>(a2);
|
||||
*a3 = 200;
|
||||
cout << "*a2 = " << *a2 << endl;
|
||||
cout << "*a3 = " << *a3 << endl;
|
||||
|
||||
// 5. 将 a3 转化为 const 指针变量【可以】
|
||||
const int *a4 = const_cast<const int *>(a3);
|
||||
// *a4 = 100;
|
||||
cout << "*a4 = " << *a4 << endl;
|
||||
cout << "*a3 = " << *a3 << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
int x;
|
||||
void show()
|
||||
{
|
||||
cout << "A show() x = " << x << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class B
|
||||
{
|
||||
public:
|
||||
int x;
|
||||
void show()
|
||||
{
|
||||
cout << "B show() x = " << x << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
A *a = new A();
|
||||
a->x = 100;
|
||||
B *b = new B();
|
||||
b->x = 200;
|
||||
|
||||
// B *b2 = static_cast<B *>(a); // error
|
||||
// B *b3 = dynamic_cast<B *>(a); // error
|
||||
B *b4 = reinterpret_cast<B *>(a); // 输出: B show() x = 100
|
||||
|
||||
b4->show();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
T &maxVal(T &a, T &b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
int x;
|
||||
|
||||
public:
|
||||
A(int x) : x(x) {}
|
||||
void show()
|
||||
{
|
||||
cout << "x = " << x << endl;
|
||||
}
|
||||
|
||||
public:
|
||||
// 重载运算符>,解决函数模版的局限性,不用具体化函数模版
|
||||
bool operator>(const A &a) const
|
||||
{
|
||||
return this->x > a.x;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
A a1(20), a2(50);
|
||||
// A &b = maxVal<A>(a1, a2);
|
||||
A &b = maxVal(a1, a2);
|
||||
b.show();
|
||||
return 0;
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// 类模版
|
||||
// 类模版是成员变量的数据类型泛化
|
||||
// 类模版的声明作用于整个类,而不是单个成员,即类的内部的任何位置都可以使用
|
||||
|
||||
// 如: 定义长方形的图形类
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 类模版
|
||||
template <typename T>
|
||||
class Rectangle
|
||||
{
|
||||
private:
|
||||
T width, height; //矩形的宽和高
|
||||
|
||||
public:
|
||||
Rectangle(T w, T h) : width(w), height(h) {}
|
||||
|
||||
public:
|
||||
void draw()
|
||||
{
|
||||
cout << "绘制矩形"
|
||||
<< "宽: " << width << "高: " << height << endl;
|
||||
}
|
||||
void length()
|
||||
{
|
||||
cout << "矩形周长: " << 2 * (width + height) << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "r1: " << endl;
|
||||
Rectangle<int> r1(10, 20);
|
||||
r1.draw();
|
||||
r1.length();
|
||||
|
||||
cout << "r2: " << endl;
|
||||
Rectangle<double> r2(10.53, 20.25);
|
||||
r2.draw();
|
||||
r2.length();
|
||||
|
||||
cout << "r3: " << endl;
|
||||
Rectangle<float> r3(10.2f, 20.2f);
|
||||
r3.draw();
|
||||
r3.length();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
// 类模版作为函数参数
|
||||
// 函数模版的参数可以是类模版
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 类模版
|
||||
template <typename T>
|
||||
class Rectangle
|
||||
{
|
||||
private:
|
||||
T width, height; //矩形的宽和高
|
||||
|
||||
public:
|
||||
Rectangle(T w, T h) : width(w), height(h) {}
|
||||
|
||||
public:
|
||||
void draw()
|
||||
{
|
||||
cout << "绘制矩形"
|
||||
<< "宽: " << width << "高: " << height << endl;
|
||||
}
|
||||
void length()
|
||||
{
|
||||
cout << "矩形周长: " << 2 * (width + height) << endl;
|
||||
}
|
||||
};
|
||||
|
||||
// 类模版作为函数参数
|
||||
// 将类模版作为函数参数,可以将类模版的数据类型泛化
|
||||
template <typename T>
|
||||
void drawShape(Rectangle<T> &r)
|
||||
{
|
||||
r.draw();
|
||||
r.length();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "r1: " << endl;
|
||||
Rectangle<int> r1(10, 20);
|
||||
drawShape<int>(r1); // 显式指定模版参数
|
||||
|
||||
cout << "r2: " << endl;
|
||||
Rectangle<double> r2(10.53, 20.25);
|
||||
drawShape<>(r2); // 空<>表示自动推导
|
||||
|
||||
cout << "r3: " << endl;
|
||||
Rectangle<float> r3(10.2f, 20.2f);
|
||||
drawShape(r3); // 表示自动推导
|
||||
|
||||
return 0;
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
// 类模版派生普通类
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
class Shape
|
||||
{
|
||||
protected:
|
||||
T iPerimeter;
|
||||
|
||||
public:
|
||||
// virtual double area() = 0;
|
||||
virtual T perimeter() { return iPerimeter; } // 周长
|
||||
};
|
||||
|
||||
class Rectangle : public Shape<int>
|
||||
{
|
||||
private:
|
||||
int width, height;
|
||||
|
||||
public:
|
||||
Rectangle(int w, int h) : width(w), height(h) { iPerimeter = 2 * (w + h); }
|
||||
};
|
||||
|
||||
class Triangle : public Shape<float>
|
||||
{
|
||||
private:
|
||||
float a, b, c;
|
||||
|
||||
public:
|
||||
Triangle(float a, float b, float c) : a(a), b(b), c(c) { iPerimeter = a + b + c; }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Rectangle r1(10, 20);
|
||||
cout << "r1周长: " << r1.perimeter() << endl;
|
||||
|
||||
Triangle t1(3.0f, 4.0f, 5.0f);
|
||||
cout << "t1周长: " << t1.perimeter() << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user