c++进阶(2)

智能指针基本知识

之前使用的类似int *p = new int(10);的都是裸指针
需要手动的释放,容易发生内存泄漏等问题

所以我们引入智能指针,可以保证资源可以自动释放!
利用栈上的对象出作用域自动析构的特征,来做到资源的自动释放

template<typename T>
class CSmartptr
{
public:
	CSmartptr(T* ptr = nullptr);
	:mptr(ptr){}
	~CSmartptr() { delete mptr };
private:
	T* mptr;
};
int main()
{
	CSmartptr<int> ptr1(new int); 
	return 0;
}

智能指针可以定义在堆上吗?

CSmartptr<int> *p = new CSmartptr<int> (new int);

可以是可以定义,但是相当于裸指针,还是需要自己手动释放。

完善智能指针的*和->运算符重载

#include<iostream>
using namespace std;

template<typename T>
class CSmartptr
{
public:
	CSmartptr(T* ptr = nullptr)
	:mptr(ptr){}
	~CSmartptr() { delete mptr; }

	T& operator*() { return *mptr; }

	T* operator->() { return mptr; }
private:
	T* mptr;
};


int main()
{

	CSmartptr<int> ptr1(new int); 
	*ptr1 = 20;//*运算符重载

	class Test
	{
	public:
		void test() { cout << "call Test::" << endl; }
	};

	CSmartptr<Test> ptr2(new Test());
	ptr2->test();//->运算符重载

	return 0;
}

不带引用计数的智能指针

实例代码:

#include<iostream>
using namespace std;

template<typename T>
class CSmartptr
{
public:
	CSmartptr(T* ptr = nullptr)
	:mptr(ptr){}
	~CSmartptr() { delete mptr; }

	T& operator*() { return *mptr; }

	T* operator->() { return mptr; }
private:
	T* mptr;
};


int main()
{
	CSmartptr<int> p1(new int);
	CSmartptr<int> p2(p1);
	return 0;
}

报错了,因为拷贝构造是浅拷贝,所以析构的时候会释放野指针。

auto_ptr
auto_ptr<int> ptr1(new int);
auto_ptr<int> ptr2(ptr1);

*ptr2 = 20;
cout << *ptr1 << endl;

报错,

auto_ptr作用是,永远让最后一个指针来管理内存,前面的都释放。所以此时ptr1已经结束了。
不太推荐auto_ptr

scoped_ptr
	scoped_ptr(const scoped_ptr<T>&) = delete;
	scoped_ptr<T>& operator=(const scoped_ptr<T>&) = delete;

scoped_ptr直接把对象的拷贝构造和赋值运算符删除了
这样我们做可能的野指针操作时,编译器会提示报错

也比较少用
那么到底用什么呢?

unique_ptr!!!
	unique_ptr(const unique_ptr<T>&) = delete;
	unique_ptr<T>& operator=(const unique_ptr<T>&) = delete;

unique_ptr也把对象的拷贝构造和赋值运算符删除了

那和scoped_ptr有什么区别吗?

	unique_ptr<int> p1(new int);
	unique_ptr<int> p2(p1);

直接用拷贝构造会显示报错

我们可以

	unique_ptr<int> p1(new int);
	unique_ptr<int> p2(std::move(p1));

std::move得到当前变量的右值类型(强转)
因为unique_ptr提供了带右值引用参数的拷贝构造函数和赋值运算符的重载函数

unique_ptr(unique_ptr<T> &&src) 
unique_ptr<T>& operator=(unique_ptr<T>&&src)

带引用计数的智能指针

可以多个智能指针共同管理同一个资源
给每一个对象资源,匹配一个引用计数
智能指针=》引用资源的时候=》引用计数+1
智能指针=》出作用域,不使用资源的时候=》引用计数-1=》!=0
如果引用计数为0了=》资源释放

shared_ptr

强智能指针:可以改变资源的引用计数

为什么不直接用强智能指针,为什么还要一个弱智能指针?

强智能指针循环引用是什么问题?造成什么结果?怎么解决?

weak_ptr

弱智能指针:不会改变资源的引用计数

share_ptr的交叉引用问题

具体智能指针相关

lambda表达式的实现原理

意义:对于简单的函数操作,Lambda 表达式可以大大减少代码量。
用于如:优先队列的大小比较,智能指针的删除器

语法:
[捕获外部变量](形参列表)->返回值{操作代码};

如: auto func1 = []()->void{cout<<"hello world!"<<endl;};

如果lambda表达式的返回值不需要,那么->可以省略
如: auto func1 = [](){cout<<"hello world!"<<endl;};

[捕获外部变量]
[]:表示不捕获任何外部变量
[]:以传值的方式捕获外部的所有变量
[&]:以传引用的方式捕获外部的所有变量
[=,&a]:以传值的方式捕获外部的所有变量,但a变量以传引用的方式捕获

c++11常用知识点总结

一:关键字和语法

  1. auto:可以根据右值,推到出右值的类型,然后左边变量的类型也就已知了。
  2. nullptr:指针专用,能和整数进行区别
  3. foreach:for(Type val:container){ cout<<val<<endl; }//底层就是通过指针或迭代器来实现的
  4. 右值引用:move移动语义函数和forward类型完美转发函数。
  5. 模板的一个新特性:typename…A 表示可变参(类型参数)

二:绑定器和函数对象

  1. bind绑定器
  2. function对象
  3. lambda表达式

三:智能指针.

  1. shared_ptr和weak_ptr

四:容器

  1. unordered_set和unordered_map;哈希表O(1){set和map是红黑树O(logn)}
  2. forward_list:前向链表(更轻量)

五:C++语言级别支持的多线程编程

  1. createThread
  2. pthread_create
  3. clone
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值