八、泛型编程简介
1、数据结构课程的特点
- 专注于数据元素之间的关系
- 专注于特定结构之上的算法
- 数据结构课程并不关注数据元素的具体类型!
2、问题
如何为数据结构的学习选择合适的语言?
3、经验分享
支持泛型编程的语言最适合数据结构课程的学习?
4、泛型编程的概念
- 不考虑具体数据类型的编程方式
5、C++中的函数模板
- 一种特殊的函数可用不同类型进行调用
- 看起来和普通函数很相似,区别是类型可被参数化
6、函数模板的语法规则
- template关键字用于声明开始进行泛型编程
- typename关键字用于声明泛指类型
7、函数模板的使用
- 自动类型推导调用
- 具体类型显示调用
8、编程实验:函数模板初探
与下一个实验在一起。
9、C++中的类模板
- 以相同的方式处理不同的类型
- 在类声明前使用template进行标识
- < typename T>用于说明类中使用的泛指类型 T
10、类模板的应用
- 只能显示指定具体类型,无法自动推导
- 使用具体类型<Type>定义对象
11、编程实验:类模板初探
#include <iostream>
using namespace std;
template <typename T>
void Swap(T& a, T& b)
{
T t = a;
a = b;
b = t;
}
template <typename T>
class Op
{
public:
T process(T v)
{
return v * v;
}
};
int main()
{
int a = 2;
int b = 1;
Swap(a, b);
cout << "a = " << a << " " << "b = " << b << endl;
double c = 0.01;
double d = 0.02;
Swap<double>(d, c);
cout << "c = " << c << " " << "d = " << d << endl;
Op<int> opInt;
Op<double> opDouble;
cout << "5 * 5 = " << opInt.process(5) << endl;
cout << "0.3 * 0.3 = " << opDouble.process(0.3) << endl;
return 0;
}
12、小结
- 模板是泛型编程理论在C++中的实现
- 函数模板支持参数的自动推导和显示指定
- 类模板在使用时只能显示指定类型
- 类模板非常适用于编写数据结构相关的代码
九、智能指针示例
1、内存泄漏(臭名昭著的Bug )
- 动态申请堆空间,用完后不归还
- C++语言中没有垃圾回收的机制(c#、java、Python有)
- 指针无法控制所指堆空间的生命周期
2、当代C++软件平台中的智能指针
- 指针生命周期结束时主动释放堆空间
- 一片堆空间最多只能由一个指针标识
- 杜绝指针运算和指针比较
3、智能指针的设计方案
- 通过类模板描述指针的行为
- 能够定义不同类型的指针对象
- 重载指针特征操作符(->和*)
- 利用对象模拟原生指针的行为
4、编程实验:智能指针
SmartPointer.h
#ifndef SMARTPOINTER_H_
#define SMARTPOINTER_H_
/*******************************************************************************
* Include Files *
*******************************************************************************/
#include "Pointer.h"
/*******************************************************************************
* Type Definition *
*******************************************************************************/
namespace DTLib
{
template <typename T> // 泛型编程 - 类模板
class SmartPointer : public Pointer<T> // 基于普通指针类
{
public:
SmartPointer(T* p = NULL) : Pointer<T>(p) // 构造函数 - 调用父类构造函数 - 默认指针为NULL
{
}
SmartPointer(const SmartPointer<T>& obj) // 拷贝构造函数
{
this->m_pointer = obj.m_pointer; // 当前对象的堆空间 指向 引入的堆空间
const_cast<SmartPointer<T>&>(obj).m_pointer = NULL; // 将原来的堆空间指针置NULL const_cast 去除对象的const属性
}
SmartPointer<T>& operator= (const SmartPointer<T>& obj) // 重载赋值操作符
{
if( this != &obj ) // 判断是否为 自赋值
{
T* p = this->m_pointer; //为了防止类异常抛出,所以最后释放堆空间
this->m_pointer = obj.m_pointer; // 当前对象的堆空间 指向 引入的堆空间
const_cast<SmartPointer<T>&>(obj).m_pointer = NULL; // 将原