C++智能指针

普通指针的不足,new和new[] 需要delete和delete[]

  • 忘了
  • 不清楚什么时候释放,比如多线程的共享一个对象时

普通指针的释放:

  • 类内的指针,在析构函数中释放
  • new 出来的类,也需要delete后才会调用析构函数

智能指针的设计思路

  • 智能指针是类模板,在栈上创建智能指针对象。
  • 把普通指针交给智能指针对象。
  • 智能指针对象过期时,调用智能指针的析构函数释放普通指针的内存
    auto_ptr已弃用,unique_ptr、shared ptr 和 weak ptr是C++11标准的

unique_ptr

unique_ptr独享指向的对象,即只有一个 unique_ptr指向一个同一个对象

模板类

通用类的描述,使用任意类型(泛型)来描述类的定义

template <class T1, class T2=默认类型,......>   //数据类型
class 类模板名
{
	类的定义;
}
template <class T1, class T2=int>   //数据类型
class AA
{
public:
	T1 m_a; //通用类型用于成员变量
	T2 m_b;
	AA() {}
	//通用类型用于成员函数的参数
	AA(T1 a, T2 b) :m_a(a), m_b(b) {}
	//通用类型用于成员参数的返回值
	T1 geta()
	{
		T1 a = 1; //通用类型用于成员函数的代码中
		return m_a + a;
	}
	T1 getb()
	{
		T1 a = 1; //通用类型用于成员函数的代码中
		return m_b + a;
	}
};

int main()
{
	AA<int, double> a;//模板类创建对象a
	a.m_a = 20;a.m_b = 30;
	cout << "a.geta()=" << a.geta() << endl;
	cout << "a.getb()=" << a.getb() << endl;
}

注意:
1)在创建对象的时候,必须指明具体的数据类型
2)使用类模板时,数据类型必须适应类模板中的代码
3)类模板可以为通用参数指定缺省的数据类型
4)类的成员函数可以在类外实现

template <class T1, class T2>   //数据类型
class AA
{
public:
	T1 m_a; //通用类型用于成员变量
	T2 m_b;
	AA() {}
	//通用类型用于成员函数的参数
	AA(T1 a, T2 b) :m_a(a), m_b(b) {}
	//通用类型用于成员参数的返回值
	T1 geta()
	{
		T1 a = 1; //通用类型用于成员函数的代码中
		return m_a + a;
	}
	T1 getb();
};

template <class T1, class T2>
T1 AA<T1,T2>::getb()
{
	T1 a = 1; //通用类型用于成员函数的代码中
	return m_b + a;
}

5)可以用 new 创建模板对象

int main()
{
	//AA<int, double> a;//模板类创建对象a
	//a.m_a = 20;a.m_b = 30;
	//cout << "a.geta()=" << a.geta() << endl;
	//cout << "a.getb()=" << a.getb() << endl;
	
	AA<int, double> *a = new AA<int, double>(20,30);
	cout << "a.geta()=" << a->geta() << endl;
	cout << "a.getb()=" << a->getb() << endl;
}

6)用模板类创建的对象,任何成员函数只要不使用,就不会创建

template <class T1, class T2=int>   //数据类型
class AA
{
public:
	T1 m_a; 
	T2 m_b;
	AA() {m_a.aaaanbbbbb();}  //肯定会出错的代码
	AA(T1 a, T2 b) :m_a(a), m_b(b) {}
};

int main()
{
	AA<int, double> *a ; //不会报错
}

模板类示例-栈

模板类最常用的就是作为容器类

class Stack
{
private:
	int* items; //栈数组
	int stacksize; //栈实际的大小
	int top; //栈顶指针 0 代表没有
public:
	Stack(int size) :stacksize(size), top(0) { //分配栈数组内存 栈顶指针初始化为0
		items = new int[stacksize]; //申请的数组首地址给指针
	}
	~Stack()
	{
		delete []items;
		items = nullptr;
	}
	//const 常量成员函数 不会修改成员变量
	bool isempty()const { //判断栈是否已空
		return top == 0;
	}
	bool isfull()const { //判断栈是否已满
		return top == stacksize;
	}

	bool push(const int& item) { //元素入栈  
		if (top < stacksize) { items[top++] = item;return true; } //先赋值,再移动top
		return false;
	}
	bool pop(int& item){ //元素出栈
		if (top > 0) { item = items[--top];return true; }
		return false;
	}
	int getTop() { return top; }
	//item = items[top];  // 先访问栈顶元素  
	//--top;              // 然后将栈顶指针减1
};
int main()
{
	Stack ss(5);
	ss.push(1);
	ss.push(2);
	ss.push(3);
	ss.push(4);
	ss.push(5);
	cout << "top=" << ss.getTop() << endl; //5
	int item;
	while (ss.isempty() == false) {
		ss.pop(item);
		cout << "item=" << item << endl;
	}
}

如果不用模板类,则使用typedef int DataType实现泛用

typedef int DataType;

class Stack
{
private:
	DataType* items; //栈数组
	int stacksize; //栈实际的大小
	int top; //栈顶指针 0 代表没有
public:
	Stack(int size) :stacksize(size), top(0) { //分配栈数组内存 栈顶指针初始化为0
		items = new DataType[stacksize]; //申请的数组首地址给指针
	}
	~Stack()
	{
		delete []items;
		items = nullptr;
	}
	//const 常量成员函数 不会修改成员变量
	bool isempty()const { //判断栈是否已空
		return top == 0;
	}
	bool isfull()const { //判断栈是否已满
		return top == stacksize;
	}

	bool push(const DataType& item) { //元素入栈  
		if (top < stacksize) { items[top++] = item;return true; } //先赋值,再移动top
		return false;
	}
	bool pop(int& item){ //元素出栈
		if (top > 0) { item = items[--top];return true; }
		return false;
	}
	int getTop() { return top; }
	//item = items[top];  // 先访问栈顶元素  
	//--top;              // 然后将栈顶指针减1
};
int main()
{
	Stack ss(5);
	ss.push(1);
	ss.push(2);
	ss.push(3);
	ss.push(4);
	ss.push(5);
	cout << "top=" << ss.getTop() << endl; //5
	DataType item;
	while (ss.isempty() == false) {
		ss.pop(item);
		cout << "item=" << item << endl;
	}
}

使用模板类

//typedef int DataType;

template<class DataType>
class Stack
{
private:
	DataType* items; //栈数组
	int stacksize; //栈实际的大小
	int top; //栈顶指针 0 代表没有
public:
	Stack(int size) :stacksize(size), top(0) { //分配栈数组内存 栈顶指针初始化为0
		items = new DataType[stacksize]; //申请的数组首地址给指针
	}
	~Stack()
	{
		delete []items;
		items = nullptr;
	}
	//const 常量成员函数 不会修改成员变量
	bool isempty()const { //判断栈是否已空
		return top == 0;
	}
	bool isfull()const { //判断栈是否已满
		return top == stacksize;
	}

	bool push(const DataType& item) { //元素入栈  
		if (top < stacksize) { items[top++] = item;return true; } //先赋值,再移动top
		return false;
	}
	bool pop(int& item){ //元素出栈
		if (top > 0) { item = items[--top];return true; }
		return false;
	}
	int getTop() { return top; }
	//item = items[top];  // 先访问栈顶元素  
	//--top;              // 然后将栈顶指针减1
};
int main()
{
	Stack<int> ss(5);
	ss.push(1);
	ss.push(2);
	ss.push(3);
	ss.push(4);
	ss.push(5);
	cout << "top=" << ss.getTop() << endl; //5
	int item;
	while (ss.isempty() == false) {
		ss.pop(item);
		cout << "item=" << item << endl;
	}
}

模板类示例-数组

  • 定长数组:array 容器
  • 可变数组:vector 容器
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值