C++11读书笔记—6(新指针)
来源:互联网 发布:url传递json对象 编辑:程序博客网 时间:2024/06/05 18:20
问:你为什么不用C/C++?
答:面对一个24小时不能中断运行的程序,程序员的一点内存错误通过积累可能带来灾难性后果。
〇、C++11版本之前的内存
之前我在C/C++基础的专区上已经说了C/C++几个大坑。
(1)野指针问题(2)重复内存释放问题(3)内存泄漏问题
在C++98中就已经有了智能指针这一说法。通过一个模板类型“auto_ptr"来实现。auto_ptr以对象的方式管理堆分配的内存,并在适当的时间析构,释放所获得的堆内存。我们这么写就可以了。
auto_ptr(new int);
auto_ptr的缺点很明显,拷贝时返回一个左值,不能调用delete[],破坏复制性等等,以至于很多C++教材直接去掉这么个神器。C++11在搞新智能指针时,直接废弃了。C++11提供3个智能指针。std::shared_ptr , std::unique_ptr , std::weak_ptr 使用前要#include <memory>
一、C++11的智能指针(本质是个模板类)
1.unique_ptr独占指针
先上代码:
unique_ptr<int> up1(new int(11));cout << *up1 << endl; //11unique_ptr<int> up3 = move(up1);cout << *up3 << endl; //11cout << *up1 << endl; //这一步会出问题,运行时错误
up1.reset(); up3.reset();//显示释放内存,不会导致运行时错误
unique_ptr,形如其名,独占指针。如果这么写unique_ptr<int> up2 = up1; 就错了,所有权仅能用move转移,转移之后原始指针就失效了。
2.shared_ptr共享指针
shared_ptr共享指针,使用引用计数,每一个shared_ptr的拷贝都指向相同的内存。在最后一个shared_ptr析构时,内存释放。
注意:
(1)不要用一个原始指针初始化多个shared_ptr:
int* ptr= new int;shared_ptr <int>p1(ptr);shared_ptr <int>p2(ptr);//logic error因为是计数方式,这么写可能会计数错误,提前析构。
(2)不要在函数实参中创建shared_ptr,如下代码:
fuction(shared_ptr <int>p1(new int),g());
有些编译器,可能是从左向右,先执行new int。如果g()发生异常,内存又泄露了。建议分开写。
(3)不要传入this指针到shared_ptr里面
(4)避免循环引用
这是智能指针的我一个最大坑(《深入应用C++》这本书说的,我只能说这很喜闻乐见)
struct A{shared_ptr<B> bptr;};struct B{shared_ptr<A> aptr;};int main(){ {//这里有一个作用 ap(new A);bp(new B);ap->bptr = bp;bp->aptr = ap; }return 0;}
其实我认为这种循环指向的问题,不管是谁都头疼。出了作用域引用计数变为1,并不会减为0。解决方法就是改为weak_ptr。
3.weak_ptr弱引用智能指针
weak_ptr是用来监视shared_ptr的。不会使引用计数加一。不管理shared_ptr内部的指针 ,主要是为了监视shared_ptr的生命周期。weak_ptr没有重载*与->,因为他不共享指针,不能操作资源。(按照定义好像不能算智能指针了)上面的程序改一下就行了。
struct A{shared_ptr<B> bptr;};struct B{weak_ptr<A> aptr;};
二、指针空值nullptr
1.指针空值的衍变
#include<iostream>using namespace std;void f(char* a){cout << "char" << endl;}void f(int a){cout << "int" << endl;}int main(){f(NULL);//注意这个return 0;}
我的原意是NULL属于空值指针(看来还是右值),应该执行上面重载函数;而书上说NULL会做转换变为0直接执行下面的void f(int a)的重载函;但是G++等编译器遇到NULL就直接报二义性错误,VS直接输出“char”。这种程序员,编译器,C++标准委员会三方不统一的情况很热闹。于是C++11创造出空值引用nullptr。
2.nullptr规则
int *p = (void*)0;//C++会犯错
int *p = nullptr;//C++11可以
(2)在C++11中,sizeof (nullptr)==sizeof((void)*)
- C++11读书笔记—6(新指针)
- 《征服C指针》——读书笔记(6)
- 读书笔记之c和指针(11)
- 读书笔记之c和指针(6)
- C和指针读书笔记-第6章(指针)
- 《C和指针》读书笔记(11)
- 《C和指针》读书笔记(6)
- 读书笔记:C和指针6
- C和指针读书笔记——指针
- 《征服C指针》——读书笔记(1)
- 《征服C指针》——读书笔记(2)
- 《征服C指针》——读书笔记(3)
- 《征服C指针》——读书笔记(4)
- 《征服C指针》——读书笔记(5)
- C和指针——读书笔记(一)
- C和指针——读书笔记(二)
- 《c程序设计语言》读书笔记(五)——指针与数组
- C和指针读书笔记——基本概念
- 算法竞赛入门经典(第二章)
- mysql中sql文件的导出与导入
- JVM之栈优化
- Git使用笔记
- WebSocket 详解
- C++11读书笔记—6(新指针)
- Masonry介绍与使用实践:快速上手Autolayout
- linux系统配置X11
- UVA11859
- jQuery EasyUI 教程-Tabs(选项卡)
- ReactNative-HelloWorld
- safe way to copy home directory from disk
- C# 调用System.Data.Sqlite 外键失效解决方案
- zcmu1733