C++11--智能指针shared_ptr,weak_ptr,unique_ptr <memory>
共享指针 shared_ptr
/*********** Shared_ptr ***********/
// 为什么要使用智能指针,直接使用裸指针经常会出现以下情况
// 1. 当指针的生命长于所指的资源:野指针
// 2. 当指针的生命短于所指的资源:资源泄漏
//
// 智能指针: 确保指针和资源的生命周期相同
class Dog {
string m_name;
public:
void bark() { cout << "Dog " << m_name << " rules!" << endl; }
Dog(string name) { cout << "Dog is created: " << name << endl; m_name = name; }
Dog() { cout << "Nameless dog created." << endl; m_name = "nameless"; }
~Dog() { cout << "dog is destroyed: " << m_name << endl; }
//void enter(DogHouse* h) { h->setDog(shared_from_this()); } // Dont's call shared_from_this() in constructor
};
class DogHouse {
shared_ptr<Dog> m_pD;
public:
void setDog(shared_ptr<Dog> p) { m_pD = p; cout << "Dog entered house." << endl;}
};
int main ()
{
shared_ptr<Dog> pD(new Dog("Gunner"));
shared_ptr<Dog> pD = make_shared<Dog>(new Dog("Gunner")); // 另一种方式,更快且更安全
pD->bark(); // 重载了箭头,可以像直接操作指针一样进行操作
cout << pD.use_count(); // 指示有多少shared_ptr指向对象
(*pD).bark();
//DogHouse h;
// DogHouse* ph = new DogHouse();
// ph->setDog(pD);
// delete ph;
//auto pD2 = make_shared<Dog>( Dog("Smokey") ); // 不要对栈上的对象使用shared_ptr
// auto pD2 = make_shared<Dog>( *(new Dog("Smokey")) );
// pD2->bark();
//
// 对象一创建就应该立马放入智能指针中,避免使用裸指针
// Dog* p = new Dog(); // 不是一个好的使用方式,容易出错
// shared_ptr<int> p1(p);
// shared_ptr<int> p2(p); // 出错,p会被delete两次
shared_ptr<Dog> pD3;
pD3.reset(new Dog("Tank"));
pD3.reset(); // Dog销毁。同: pD3 = nullptr;
//
//pD3.reset(pD.get()); // crashes返回raw point
/********** 自定义Deleter ************/
shared_ptr<Dog> pD4( new Dog("Victor"),
[](Dog* p) {cout << "deleting a dog.\n"; delete p;}
);
// 默认的deleter是operator delete.
//shared_ptr<Dog> pDD(new Dog[3]); // Dog[1]和Dog[2]内存泄漏
shared_ptr<Dog> pDD(new Dog[3], [](Dog* p) {delete[] p;} ); // 所有3个Dog都会被delete
弱指针 weak_ptr
/*********** weak_ptr *********************/
// weak_ptr对所指对象没有所有权
// 对象何时delete,怎么delete跟我没有关系
// 所以weak_ptr不是一直有效的,需要检查有效性。
class Dog {
//shared_ptr<Dog> m_pFriend;
weak_ptr<Dog> m_pFriend; //跟Dog* m_pFriend类似,不过提供了一层保护,没有人可以delete它。并不是永远有效的,如果weak_ptr指向的指针被delete了
public:
string m_name;
void bark() { cout << "Dog " << m_name << " rules!" << endl; }
Dog(string name) { cout << "Dog is created: " << name << endl; m_name = name; }
~Dog() { cout << "dog is destroyed: " << m_name << endl; }
void makeFriend(shared_ptr<Dog> f) { m_pFriend = f; }
void showFriend() { //cout << "My friend is: " << m_pFriend.lock()->m_name << endl;
if (!m_pFriend.expired()) cout << "My friend is: " << m_pFriend.lock()->m_name << endl;
cout << " He is owned by " << m_pFriend.use_count() << " pointers." << endl; }//lock()将其转化为shared_ptr,检查指针有效性,同时保证指针不被delete
};
int main () //使用共享指针的话,会资源泄漏。因为循环引用。
{
shared_ptr<Dog> pD(new Dog("Gunner"));
shared_ptr<Dog> pD2(new Dog("Smokey"));
pD->makeFriend(pD2);
pD2->makeFriend(pD);
pD->showFriend();
}
unique_ptr
/*********** unique_ptr *********************/
// Unique指针:独占对象所有权,开销比shared_ptr小
class Dog {
//Bone* pB;
unique_ptr<Bone> pB; // 防止内存泄漏,即使构造函数在new之后抛出异常
public:
string m_name;
void bark() { cout << "Dog " << m_name << " rules!" << endl; }
Dog() { pB = new Bone(); cout << "Nameless dog created." << endl; m_name = "nameless"; }
Dog(string name) { cout << "Dog is created: " << name << endl; m_name = name; }
~Dog() { delete pB; cout << "dog is destroyed: " << m_name << endl; }
};
void test() {
//Dog* pD = new Dog("Gunner");
unique_ptr<Dog> pD(new Dog("Gunner"));
pD->bark();
/* pD做许多操作*/
//Dog* p = pD.release(); //返回raw point,同时转让原对象的所有权,不会再自动delete Dog
pD = nullptr; // Dog("Gunner")被销毁
//pD.reset(new Dog("Smokey")); // Dog("Gunner")被销毁
if (!pD) {
cout << "pD is empty.\n";
}
//delete pD;
}
void f(unique_ptr<Dog> p) {
p->bark();
}
unique_ptr<Dog> getDog() {
unique_ptr<Dog> p(new Dog("Smokey"));
return p; // 传值返回,会自动使用move语义
}
void test2() {
unique_ptr<Dog> pD(new Dog("Gunner"));
unique_ptr<Dog> pD2(new Dog("Smokey"));
pD2 = move(pD);
// 1. Smokey is destroyed
// 2. pD becomes empty.
// 3. pD2 owns Gunner.
pD2->bark();
// f(move(pD)); // "Gunner"所有权已不属于pD,在f结束后销毁
// if (!pD) {
// cout << "pD is empty.\n";
// }
//
// unique_ptr<Dog> pD2 = getDog();
// pD2->bark();
unique_ptr<Dog[]> dogs(new Dog[3]); //参数支持数组,不需要像shared_ptr定义deleter。因为unique_ptr对数组进行了偏特化
dogs[1].bark();
//(*dogs).bark(); // * is not defined
}
void test3() {
// prevent resource leak even when constructor fails
}
int main ()
{
test2();
}
C++11--智能指针shared_ptr,weak_ptr,unique_ptr <memory>的更多相关文章
- C++11智能指针之std::unique_ptr
C++11智能指针之std::unique_ptr uniqut_ptr是一种对资源具有排他性拥有权的智能指针,即一个对象资源只能同时被一个unique_ptr指向. 一.初始化方式 通过new云 ...
- 【C++11新特性】 C++11智能指针之weak_ptr
如题,我们今天要讲的是C++11引入的三种智能指针中的最后一个:weak_ptr.在学习weak_ptr之前最好对shared_ptr有所了解.如果你还不知道shared_ptr是何物,可以看看我的另 ...
- C++11——智能指针
1. 介绍 一般一个程序在内存中可以大体划分为三部分——静态内存(局部的static对象.类static数据成员以及所有定义在函数或者类之外的变量).栈内存(保存和定义在函数或者类内部的变量)和动态内 ...
- c++11 智能指针 unique_ptr、shared_ptr与weak_ptr
c++11 智能指针 unique_ptr.shared_ptr与weak_ptr C++11中有unique_ptr.shared_ptr与weak_ptr等智能指针(smart pointer), ...
- 深入学习c++--智能指针(二) weak_ptr(打破shared_ptr循环引用)
1. 几种智能指针 1. auto_ptr: c++11中推荐不使用他(放弃) 2. shared_ptr: 拥有共享对象所有权语义的智能指针 3. unique_ptr: 拥有独有对象所有权语义的智 ...
- c/c++ 智能指针 shared_ptr 使用
智能指针 shared_ptr 使用 上一篇智能指针是啥玩意,介绍了什么是智能指针. 这一篇简单说说如何使用智能指针. 一,智能指针分3类:今天只唠唠shared_ptr shared_ptr uni ...
- C++智能指针shared_ptr
shared_ptr 这里有一个你在标准库中找不到的—引用数智能指针.大部分人都应当有过使用智能指针的经历,并且已经有很多关于引用数的文章.最重要的一个细节是引用数是如何被执行的—插入,意思是说你将引 ...
- C++11智能指针读书笔记;
智能指针是一个类对象,而非一个指针对象. 原始指针:通过new建立的*指针 智能指针:通过智能指针关键字(unique_ptr, shared_ptr ,weak_ptr)建立的指针 它的一种通用实现 ...
- c/c++ 智能指针 shared_ptr 和 new结合使用
智能指针 shared_ptr 和 new结合使用 用make_shared函数初始化shared_ptr是最推荐的,但有的时候还是需要用new关键字来初始化shared_ptr. 一,先来个表格,唠 ...
- 详解C++11智能指针
前言 C++里面的四个智能指针: auto_ptr, unique_ptr,shared_ptr, weak_ptr 其中后三个是C++11支持,并且第一个已经被C++11弃用. C++11智能指针介 ...
随机推荐
- golang相关网摘
1.golang开发50个坑 http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/index.html#mli ...
- 20155219 2016-2017-2 《Java程序设计》第5周学习总结
20155219 2016-2017-2 <Java程序设计>第5周学习总结 教材学习内容总结 异常处理 语法与继承构架 异常就是程序在运行时出现的不正常情况.java中的错误以对象的方式 ...
- 51nod- 【1042 数字0-9的数量 】
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1042 题目: 1042 数字0-9的数量 基准时间限制:1 ...
- guling code细节
detect_hand.py 分水岭算法: 任何一幅灰度图像都可以被看成拓扑平面,灰度值高的区域可以被看成是山峰,灰度值低的区域可以被看成是山谷.我们向每一个山谷中灌不同颜色的水,随着水的位的升高,不 ...
- A Spy in the Metro(UVA 1025 ACM/ICPC World Finals2003)
---恢复内容开始--- 题意:有n(2<=n<=50)个车站,从左到右编号为1~n,有M1辆列车从第1站向右开,还有M2辆列车从第N站向左开.在时刻0,间谍从第1站出发,目的是在时刻T( ...
- rest-framework之视图
rest-framework之视图 本文目录 一 基本视图 二 mixin类和generice类编写视图 三 使用generics 下ListCreateAPIView,RetrieveUpdateD ...
- (15)模型层-什么是ORM
ORM是什么 1.MVC或者MTV框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发 ...
- hdu1846 Brave Game 博弈
十年前读大学的时候,中国每年都要从国外引进一些电影大片,其中有一部电影就叫<勇敢者的游戏>(英文名称:Zathura),一直到现在,我依然对于电影中的部分电脑特技印象深刻.今天,大家选择上 ...
- hfrk2410_a1.1开发板移植linux-2.6.32.27--网卡篇(cs8900)
硬件:恒丰锐科开发板hfrk2410_A1.1 软件:linux-2.6.32.27 cs8900网卡移植: 将cs8900驱动源代码文件拷贝至drivers/net/,修改drivers/net/K ...
- 验证远程主机SSH指纹
转自:https://marskid.net/2018/02/05/how-to-verify-ssh-public-key-fingerprint/ 使用SSH进行远程连接新的主机的时候,经常会看到 ...