智能指针

3.智能指针之unique_ptr

匿名 (未验证) 提交于 2019-12-03 00:29:01
3.智能指针之unique_ptr 一、unique_ptrauto_ptr void fun() { int *a = new int(1000); //do something delete a; } return c++ unique _ptr unique_ptr“exclusive ownership”(专属所有权)设计的,专属所有权就是确保了在同一时间一个指针拥有一个对象的全部资源。 unique_ptrp++ void fun() { unique_ptr<int> a(new int(1000)); //do something } unique_ptr unique_ptr<string>p1 = new string(“string”);//错误 unique_ptr<int>p2(new int(100)); unique_ptr std::unique_ptr<std::string>p;//p p = nullptr; p.reset(); p p 我们也可以这样去检测: release() unique_ptr std::string *p2 = p.release();//p == nullptr unique_ptr unique_ptr exclusive ownership std::string* sp = new std::string(

智能指针的使用注意事项

匿名 (未验证) 提交于 2019-12-02 23:34:01
因为智能指针是通过引用计数的方式来进行判断何时进行析构的, 1)所以不要对含有智能指针的结构体进行memcpy,因为memcpy不会增加引用计数,从而导致错误; 2)不要对智能指针本身进行memcpy,同样因为memcpy不会增加引用计数,从而导致错误; 3)如果结构体中放有智能指针,则注意不要使用memecpy等防止进行内存拷贝,如果要发生内存拷贝,就应该放普通指针; 结构体设计时就要考虑到该结构体被谁使用,有几份等因素,来决定结构体中是否需要放结构体对象还是结构体指针,另外结构体中放指针时,尽量使用普通指针,便于维护; 结构体中,智能指针和普通指针可以并存;但是联合体中就不能放智能指针了,因为智能指针是模板类,大小不是四个字节,不好估计其大小。 文章来源: https://blog.csdn.net/dbdxnuliba/article/details/90286748

C++11智能指针和引用

匿名 (未验证) 提交于 2019-12-02 22:56:40
最近在学习课程的时候发现一个很困惑的问题,上代码 class DataHeader; class LoginResult:public DataHeader; typedef std::shared_ptr<DataHeader> DataHeaerPtr; //原型 void addSendTask(ClientSocketPtr& pClient, DataHeaderPtr& header) //未报错调用 DataHeaderPtr ret = std::make_shared<LoginResult>(); pCellServer->addSendTask(pClient, ret); //报错调用 auto ret = std::make_shared<LoginResult>(); pCellServer->addSendTask(pClient, (DataHeaderPtr)ret); #错误代码:(DataHeaderPtr)ret 错误类型: 非常量引用的初始值必须为左值。 测试环境为vc2017。 疑问: 学习的电子课件中为vc2013,这里并不会报错。在vc2017导入课件中的源码这里也不会报错。这是什么原因????????????

c++ 智能指针

对着背影说爱祢 提交于 2019-12-02 20:05:05
在使用指针的时候容易产生 内存泄漏 ( 在申请后没有释放 )   -动态申请堆空间,用完不归还。这样就导致越来越多的堆空间不能够被使用到。   -C++语言中没有垃圾回收的机制   -指针无法控制所指堆空间的声明周期(但是类的构析函数可以)。  例如如下代码: #include <iostream> using namespace std; class testPointer { int i; public: int getValue() { return i; } testPointer(int i)//构造函数 { this->i = i;//赋值 cout << "Test(int i)" <<endl; } ~testPointer()//构析函数 { cout << "~Test()" <<endl; } }; int main() { for(int i = 0 ; i< 10 ;i++) { testPointer *p = new testPointer(i); cout << p->getValue() <<endl; } return 0; } 上面代码在堆空间动态申请 testPointer 类,但是没有使用 delete 关键字来释放 testPointer 这样将导致内存泄漏。   代码运行结果:    Test(int i) 0 Test(int i)

c++11之智能指针

好久不见. 提交于 2019-12-01 13:07:01
由于在c++中我们可以动态分配内存,但有时候我们会忘记用 delete或free释放内存,就会导致内存泄露。所以c++11提供了智能指针这种东西 本文参考了知乎某知乎友的 https://www.zhihu.com/people/mo-shan-zhe/activities 比如下面这两种情况 //1 内存泄漏 str1所指的资源没有被释放 { string* str1 = new string("hello"); string* str2 = new string("world"); } //2 多重释放,引起程序崩溃 { string* str1 = new string("hello"); delete str1; //... delete str1;//引起程序崩溃 }  可能平时都写在一个文件不会忘记释放内存,但如果是一个大的项目就出问题了 然后是智能指针的赋值方式和普通指针有差异 可以在定义时就可以动态分配内存单元,但不允许先定义智能指针,再为其动态分配内存空间 再然后普通指针和智能指针之间的赋值也得很注意, 不能把智能指针指向普通内存变量,或者把非智能指针赋值给智能指针。 但可以把智能指针赋值给普通指针,但不是那么直接,需要通过智能指针的get()成员函数获取智能指针中的指针后 再赋值给普通指针 1.先说一下 auto_prt是c++98标准定义的独占智能指针

shared_ptr

不羁的心 提交于 2019-12-01 07:58:17
原文: https://www.cnblogs.com/wangkeqin/p/9351191.html   c++中动态内存的管理是通过new和delete来完成的,只要保证new和delete的配对使用,是没有问题的。但是有时候我们会忘记释放内存,甚至有时候我们根本就不知道什么时候释放内存。特别时在多个线程间共享数据时,更难判断内存该何使释放。这种情况下就机器容易产生引用非法内存的指针。                                                                                                       为了更容易(同时也更安全的管)的使用动态内存,新的标准库(C++11)提供了两种智能指针(smart pointer)类型来管理动态对象。智能指针的行为类似于常规指针。重要的区别是它负责自动释放所指向的对象。新标准提供的这两种智能指针的区别在于管理底层指针的方式:shared_ptr允许多个指针指向同一个对象;unique_ptr则独占所指向的对象。标准库还定义了一个weak_ptr的伴随类,他是一种弱引用,指向shared_ptr所管理的对象。这三种类型都定义在memory头文件中。 初始化 sahred_ptr   智能指针的使用方式与普通指针类似。解引用一个智能指针返回它指向的对象

智能指针原理及实现(1)shared_ptr

人盡茶涼 提交于 2019-12-01 02:19:55
智能指针原理及实现(1)shared_ptr 0、异常安全 C++没有内存回收机制,每次程序员new出来的对象需要手动delete,流程复杂时可能会漏掉delete,导致内存泄漏。于是C++引入智能指针,可用于动态资源管理,资源即对象的管理策略。 使用 raw pointer 管理动态内存时,经常会遇到这样的问题: 忘记 delete 内存,造成内存泄露。 出现异常时,不会执行 delete ,造成内存泄露。 下面的代码解释了,当一个操作发生异常时,会导致 delete 不会被执行: 1 void func() 2 { 3 auto ptr = new Widget; 4 // 执行一个会抛出异常的操作 5 func_throw_exception(); 6 7 delete ptr; 8 } 在C++98中,为了写出异常安全的代码,代码经常写的很笨拙,如下: 1 void func() 2 { 3 auto ptr = new Widget; 4 try { 5 func_throw_exception(); 6 } 7 catch(...) { 8 delete ptr; 9 throw; 10 } 11 delete ptr; 12 } 使用智能指针能轻易写出异常安全的代码,因为当对象退出作用域时,智能指针将自动调用对象的析构函数,避免内存泄露。 一、智能指针 shared

C++智能指针

风格不统一 提交于 2019-12-01 00:05:00
智能指针介绍 C++在堆上申请的内存,需要程序员自己去手动释放,这个内存很容易忘记释放或者在释放之前遭遇了异常,造成内存泄露。 堆内存的多次释放,会造成程序崩溃,同样,访问已经释放的内存也会造成不可预期的错误,而这些问题,都可以用智能指针来解决。 智能指针,主要用于堆内存的管理,在堆上生成的对象,可由智能指针进行管理,程序员无需手动释放,堆上的内存。 智能指针简易代码实现 ···c/c++ include template < typename T > class SmartPointer { public: SmartPointer(T * p):ptr_(p) { std::cout << "create smart pointer" << std::endl; user_count_ = new int (1); } SmartPointer(const SmartPointer & s_ptr) { std::cout << "copy constructor is called" << std::endl; ptr_ = s_ptr.ptr_; user_count_ = s_ptr.user_count_; ++(*user_count_); } SmartPointer & operator=(const SmartPointer & s_ptr) { std:

智能指针是否线程安全

不问归期 提交于 2019-11-30 19:36:46
1.9 再论shared_ptr 的线程安全 虽然我们借shared_ptr 来实现线程安全的对象释放,但是shared_ptr 本身不是100% 线程安全的。它的引用计数本身是安全且无锁的,但对象的读写则不是,因为shared_ptr 有两个数据成员,读写操作不能原子化。根据文档11,shared_ptr 的线程安全级别和内建类型、标准库容器、std::string 一样,即: 一个shared_ptr 对象实体可被多个线程同时读取; 两个shared_ptr 对象实体可以被两个线程同时写入,“析构”算写操作; 如果要从多个线程读写同一个shared_ptr 对象,那么需要加锁。 请注意,以上是shared_ptr 对象本身的线程安全级别,不是它管理的对象的线程安全级别。 要在多个线程中同时访问同一个shared_ptr,正确的做法是用mutex 保护: MutexLock mutex; // No need for ReaderWriterLock shared_ptr < Foo > globalPtr; // 我们的任务是把globalPtr 安全地传给doit() void doit(const shared_ptr < Foo >& pFoo); globalPtr 能被多个线程看到,那么它的读写需要加锁。注意我们不必用读写锁,而只用最简单的互斥锁,这是为了性能考虑

智能指针

浪子不回头ぞ 提交于 2019-11-30 19:34:36
一、智能指针 shared_ptr 智能指针主要有三种:shared_ptr,unique_ptr和weak_ptr。 shared_ptr shared_ptr是最常用的智能指针(项目中我只用过shared_ptr)。shared_ptr采用了引用计数器,多个shared_ptr中的T *ptr指向同一个内存区域(同一个对象),并共同维护同一个引用计数器。shared_ptr定义如下,记录同一个实例被引用的次数,当引用次数大于0时可用,等于0时释放内存。 注意避免循环引用 ,shared_ptr的一个最大的陷阱是循环引用,循环,循环引用会导致堆内存无法正确释放,导致内存泄漏。循环引用在weak_ptr中介绍。 1 temple<typename T> 2 class SharedPtr { 3 public: 4 ... 5 private: 6 T *_ptr; 7 int *_refCount; //should be int*, rather than int 8 }; shared_ptr对象每次离开作用域时会自动调用析构函数,而析构函数并不像其他类的析构函数一样,而是在释放内存是先判断引用计数器是否为0。等于0才做delete操作,否则只对引用计数器左减一操作。 1 ~SharedPtr() 2 { 3 if (_ptr && --*_refCount == 0) {