shared_ptr
智能指针 shared_ptr 的声明初始化方式
由于指针指针使用explicit参数 必须显示声明初始化
shared_ptr<string> pNico = new string("nico"); // ERROR
shared_ptr<string> pNico{new string("nico")}; // OK

也可以使用make_shared()
shared_ptr<string> pNico = make_shared<string>("nico");
shared_ptr<string> pJutta = make_shared<string>("jutta");

智能指针一旦声明
就不能再次分配 除非使用reset()
shared_ptr<string> pNico4;
pNico4 = new string("nico");
//ERROR: no assignment for ordinary pointers
pNico4.reset(new string("nico")); // OK

shared_ptr的使用方式与实际指针使用类似 基本没什么区别

示例 sharedPtrTest1()

//=======================================
对于shared_ptr中的参数 可以指定 删除器 Deleter
示例 sharedPtrTest2()

#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <fstream> //for ofstream
#include <cstdio> //for remove() using namespace std; void sharedPtrTest1()
{
shared_ptr<string> pNico(new string("nico"));
shared_ptr<string> pJutta(new string("jutta")); (*pNico)[0] = 'N';
pJutta->replace(0, 1, "J"); vector<shared_ptr<string>> whoMadeCoffee;
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pNico);
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pNico); for (auto ptr : whoMadeCoffee) {
cout << *ptr << " ";
}
cout << endl;
// overwrite a name again
*pNico = "Nicolai";
// print all elements again
for (auto ptr : whoMadeCoffee) {
cout << *ptr << " ";
}
cout << endl;
// print some internal data
cout << "use_count: " << whoMadeCoffee[0].use_count() << endl;
} class FileDeleter
{
private:
std::string filename;
public:
FileDeleter(const std::string& fn)
: filename(fn) {
}
void operator () (std::ofstream* fp) {
fp->close(); //close.file
std::remove(filename.c_str()); //delete file
cout << "delete file finish" << endl;
}
}; void sharedPtrTest2()
{
shared_ptr<std::ofstream> fp(new std::ofstream("tmpfile.txt"),
FileDeleter("tmpfile.txt"));
} int _tmain(int argc, _TCHAR* argv[])
{
sharedPtrTest1();
sharedPtrTest2(); return 0;
}

  

shared_ptr的误用

下面是错误示例

int* p = new int;

shared_ptr<int> sp1(p);

shared_ptr<int> sp2(p);

这将产生错误 对于int指针有两个智能指针的内存管理器对其进行管理

sp1 sp2 都对其关联的资源进行释放

正确的代码如下:

shared_ptr<int> sp1(new int);

shared_ptr<int> sp2(sp1);

还有一种隐蔽的情况 也会发生这种错误:

比如在Person 中增加一个函数setParentsAndTheirKids()

void setParentsAndTheirKids(shared_ptr<Person> m = nullptr,
shared_ptr<Person> f = nullptr)
{
mother = m;
father = f;
if (m != nullptr){
m->kids.push_back(shared_ptr<Person>(this));
}
if (f != nullptr){
f->kids.push_back(shared_ptr<Person>(thid));
}
}

int _tmain(int argc, _TCHAR* argv[])
{
string name("nico");
shared_ptr<Person> mom(new Person(name + "'s mom"));
shared_ptr<Person> dad(new Person(name + "'s dad"));
shared_ptr<Person> kid(new Person(name + "name"));

kid->setParentsAndTheirKids(mom,dad);

return 0;
}

但是如果在自己的类中使用包含this的shared_ptr指针 会增加引用计数

导致无法释放

所以引进enable_shared_from_this类

#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std; class Person : public std::enable_shared_from_this<Person> {
public:
string name;
shared_ptr<Person> mother;
shared_ptr<Person> father;
//vector<shared_ptr<Person>> kids;
vector<weak_ptr<Person>> kids; Person(const string& n,
shared_ptr<Person> m = nullptr,
shared_ptr<Person> f = nullptr)
:name(n), mother(m), father(f){
}; ~Person(){
cout << "delete " << name << endl;
} //====================================
void setParentsAndTheirKids(shared_ptr<Person> m = nullptr,
shared_ptr<Person> f = nullptr)
{
mother = m;
father = f;
if (m != nullptr){
m->kids.push_back(shared_ptr<Person>(shared_from_this()));
}
if (f != nullptr){
f->kids.push_back(shared_ptr<Person>(shared_from_this()));
}
}
}; int _tmain(int argc, _TCHAR* argv[])
{
string name("nico");
shared_ptr<Person> mom(new Person(name + "'s mom"));
shared_ptr<Person> dad(new Person(name + "'s dad"));
shared_ptr<Person> kid(new Person(name + "name")); kid->setParentsAndTheirKids(mom,dad); return 0;
}

  

c++11 stl 学习之 shared_ptr的更多相关文章

  1. c++11 stl 学习之 pair

    pair以模板的方式存储两个数据 namespace std {template <typename T1, typename T2>struct pair {// memberT1 fi ...

  2. 侯捷STL学习(11)--算仿+仿函数+适配器

    layout: post title: 侯捷STL学习(十一) date: 2017-07-24 tag: 侯捷STL --- 第三讲 标准库内核分析-算法 标准库算法形式 iterator分类 不同 ...

  3. ###STL学习--关联容器

    点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的关联容器. ###stl学习 |--迭 ...

  4. STL学习:STL库vector、string、set、map用法

    本文仅介绍了如何使用它们常用的方法. vector 1.可随机访问,可在尾部插入元素:2.内存自动管理:3.头文件#include <vector> 1.创建vector对象 一维: (1 ...

  5. Effective STL 学习笔记 32 ~ 33

    Effective STL 学习笔记 32 ~ 33 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

  6. Effective STL 学习笔记: Item 22 ~ 24

    Effective STL 学习笔记: Item 22 ~ 24 */--> div.org-src-container { font-size: 85%; font-family: monos ...

  7. map--C++ STL 学习

    map–C++ STL 学习   Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力.   说下map内 ...

  8. 标准模板库(STL)学习探究之stack

    标准模板库(STL)学习探究之stack queue priority_queue list map/multimap dequeue string

  9. 标准模板库(STL)学习探究之vector容器

    标准模板库(STL)学习探究之vector容器  C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被 ...

随机推荐

  1. Dictionary在多线程情况下

    Add时出错 错误信息: Index was outside the bounds of the array. 详细信息: at System.Collections.Generic.Dictiona ...

  2. XSSExcelUtil

    package com.numa.util; import org.apache.poi.hssf.usermodel.*;import org.apache.poi.hssf.util.HSSFCo ...

  3. 安装好kali要做的事

    更换更新源 vim /etc/apt/sources.list #中科大deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free c ...

  4. day11 闭包函数和装饰器

    1.函数不是新知识点 主要是学习函数的用法 在面向对象编程中,一切皆对象,函数也不例外 具体的表现 1.函数可以引用 2.函数可以作为函数的参数 3.函数可以作为函数的返回值 4.可以被存储到容器类型 ...

  5. Android的框架功能说明

    OkHttp网络框架 Picasso图片缓存框架 ORMLite数据库框架 GreenDao数据库框架

  6. EM算法之GMM聚类

    以下为GMM聚类程序 import pandas as pd import matplotlib.pyplot as plt import numpy as np data=pd.read_csv(' ...

  7. YII2中ActiveDataProvider与GridView的配合使用

    YII2中ActiveDataProvider可以使用yii\db\Query或yii\db\ActiveQuery的对象,方便我们构造复杂的查询筛选语句. 配合强大的GridView,快速的显示我们 ...

  8. sqlserver中对于特定数据字段定义特定的数据类型

    char和varchar:汉字占两个字节,英文.数字或字符占一个 比如: 性别:男   女 可以定义为:char(2)或者是varchar(2)    因为性别是中文,中文占两个字节 nchar和nv ...

  9. 地图调起URI API(通过连接直接调用百度地图)

    网站:http://lbsyun.baidu.com/index.php?title=uri/api/web 地图调起URI API 百度地图URI API是为开发者提供直接调起百度地图产品(百度We ...

  10. 9.27 h5日记

    9.27 1.怎样给title前加小图标? <link rel="short icon"  href="favicon.ico"/> ❤link有哪 ...