智能指针和函数模板

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

 

一、类型信息

C++中有typeid运算符可以获取数据的类型,使用时需要添加头文件typeinfo

1、运算结果是 type_info 的类型对象

2、使用type_info类里面的成员函数name,可以获取数据的类型名

typeid(数据).name() 返回字符串表示类型名

3、type_info还重载了 == 运算符,可以判断两个数据的类型是否一样

if(typeid(数据1) == typeid(数据2)) // 类型相同

4、可以区别父类指针或引用指向的是哪个子类,但前提是父子类之间构成多态

Base* b1 = new Son;

Base* b2 = new Base;

if(typeid(*b1) == typeid(*b2))

{

// 如果Base和Son构成多态 结果是不相同

// 不构成多态,结果永远相同

}

5、typeid不能进行运算符函数重载

二、智能指针

常规指针的缺点:

当一个常规指针离开了作用域时,只有该指针变量本身所占用的内存空间(4\8字节)会被自动释放,而它所指向的内存空间不一定会释放,可能由于free、delete、delete[] 语句没有执行或者忘记写都会导致内存泄漏

什么是智能指针:

智能指针是一个封装了常规指针的类类型对象,但是它里面重载了 * -> 运算符,可以像常规指针一样使用

智能指针的优点:

因为智能指针是一个类类型对象,因此当它离开作用域时,会自动调用它的析构函数,析构函数中有释放常规指针所指向内存的语句,从而实现自动释放内存的效果,避免内存泄漏

C++中如何使用智能指针: C++98标准

#include

auto_ptr<类型> ptr(new 类型);

此时,ptr就可以像常规指针一样使用即可,使用结束后不用专门释放内存

智能指针的缺点:

1、不能多个智能指针指向同一个对象,因为它们是浅拷贝,会在析构函数时重复释放相同的内存导致内存崩溃

2、不能指向对象数组,析构函数中没有使用 delete[]

3、不能放入容器中

三、什么是模板

是一种自动生成代码的技术,这种技术能让程序员在编写代码时不需要考虑数据类型,这种技术也称为泛型编程

四、为什么要使用模板

1、C/C++是一种静态编程语言(编写->预处理->编译->汇编->链接->可执行文件),缺点是实现代码的通用很麻烦,优点是运行速度较快

任务:实现一个通用的快速排序算法 参考 标准库中的qsort

void qsort(void *base, size_t nmemb, size_t size,

int (*compar)(const void *, const void *));

2、C语言是借助回调模式实现通用代码,实现难度高,使用也很麻烦

3、还可以借助宏函数实现通用代码,类型检查不严格、没有返回值、容易出错swap

4、C++中还可以借助函数重载实现代码通用,但是导致代码量增加,未知类型无法解决

5、基于以上原因,C++之父在C++中实现了模板技术,从而让C++的编程彻底摆脱了数据类型的困扰

四、函数模板

1、函数模板的定义

template

T3 函数名(T1 参数1,T2 参数2)

{

}

T1 T2...都是未知类型,可以是任何名字,一般约定俗成使用T

2、函数模板的原理

函数模板要经历两次编译:

a、检查函数模板的语法是否错误,但是此时不会生成函数的二进制指令

b、根据调用者提供的参数类型再次检查函数代码,如果替换后还是没有错误,才会最终生成二进制指令存储在代码段

3、函数模板的调用全过程

C++编译器并不会把函数模板当成一个函数实体,而是当做一个生成函数的模具,当调用该函数提供了具体类型的参数时,才会生成一个函数实体

调用函数模板的第一步就是提供未知类型的具体类型参数:

自动:程序员调用函数,编译器会自动根据函数的实参类型获取类型参数

手动:函数名(参数);

注意:如果自动方式不可以获取到所有的未知类型,则需要使用手动方式把所有的未知类型都传递给函数模板

使用函数模板生成函数实体的过程,称为函数的实例化

4、函数模板的默认形参

template

T3 函数名(T1 参数1,T2 参数2)

{

}

函数模板的未知类型也可以像普通函数的参数一样设置默认形参,规则语法与普通函数一致,但是只有C++11语法标准才支持,需要加编译参数

-std=gnu++11

5、模板的特化

模板虽好但是并不能解决所有的问题,有一些特殊类型与普通类型的运算规则不同,以此需要给特殊类型实现一个特殊版本,例如:char*

编译器会优先调用普通函数,因此不会与函数模板冲突

作业:

实现二分查找、冒泡、选择、插入、快速、归并、堆等算法的函数模板

你可能感兴趣的:(c++,开发语言)