C++智能指针(三)总结

https://blog.csdn.net/nou_camp/article/details/70195795

在上一篇博客中(C++智能指针(二))模拟实现了三种智能指针。 

其中最好的就是shared_ptr,但是这并不代表它就是最完美的,它也有问题,这个问题就是循环引用问题。下面用一段代码来解释说明循环引用问题。
#include<memory>
struct  ListNode
{shared_ptr<ListNode> _next;shared_ptr<ListNode> _prev;int _data;ListNode(int x):_data(x), _next(NULL), _prev(NULL){}~ListNode(){cout << "~ListNode()" << endl;}
};void test()
{shared_ptr<ListNode> ap1(new ListNode(10));shared_ptr<ListNode> ap2(new ListNode(20));ap1->_next = ap2;ap2->_prev = ap1;
}
int main()
{test();system("pause");return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

这里写图片描述

这就是shared_ptr的缺陷–循环引用问题 
这里写图片描述

为了解决循环引用的问题,引进了弱指针weak_ptr 
weak_ ptr是一种不控制所指向对象的智能指针,它指向由一个shared_ptr管理的对象。将一个weak_ptr绑定到一个shared_ptr 不会改变shared_ptr的引用计数 
测试代码如下

#include<iostream>
using namespace std;
#include<memory>
struct  ListNode
{weak_ptr<ListNode> _next;weak_ptr<ListNode> _prev;int _data;ListNode(int x):_data(x){}~ListNode(){cout << "~ListNode()" << endl;}
};void test()
{shared_ptr<ListNode> ap1(new ListNode(10));shared_ptr<ListNode> ap2(new ListNode(20));ap1->_next = ap2;ap2->_prev = ap1;
}
int main()
{test();system("pause");return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

仿函数:仿函数(functor),就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了。

template<class T>
struct Less
{bool operator()(const T& l, const T& r){return l < r;}
};
void Test2()
{Less<int>less1;cout << less1(1, 2) << endl;
}
int main()
{Test2();system("pause");return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

定制删除器和空间分配器

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<memory>
class FClose
{
public:void operator()(void* ptr){cout << "fclose" << endl;fclose((FILE*)ptr);}
};
class Free
{
public:void operator()(void* ptr){cout << "free" << endl;free(ptr);}
};void test() 
{//定制删除器shared_ptr<FILE>p1(fopen("test.txt", "w"), FClose());//定制删除器和分配器shared_ptr<int> p2((int*)malloc(sizeof(int)), Free(), allocator<int>());
}
int main()
{test();system("pause");return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

智能指针总结 
智能指针可以提供对动态分配的内存安全而方便的管理,但这建立在正确的使用前提下。 
1.不使用相同的内置指针值初始化(或reset)多个智能指针。 
2.不delete get( )返回的指针。(p.get( )返回p中保存的指针。要小心使用,若智能指针释放了其对象,返回的指针所指向的对象也就消失了) 
3.不使用get()初始化或reset另一个智能指针。 
4.如果使用get( )返回的指针,记住当最后一个对应的智能指针销毁后,你的指针就变成无效了。 
5.使用智能指针管理的资源不是new分配的内存,记住传递给他一个定制的删除器。  


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383750.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

POJ2114-Boatherds-树分治

题目描述 Boatherds Inc. is a sailing company operating in the country of Trabantustan and offering boat trips on Trabantian rivers. All the rivers originate somewhere in the mountains and on their way down to the lowlands they gradually join and finally th…

c++11 你需要知道这些就够了

https://blog.csdn.net/tangliguantou/article/details/50549751c11新特性举着火把寻找电灯今天我就权当抛砖引玉&#xff0c;如有不解大家一起探讨。有部分内容是引用自互联网上的内容&#xff0c;如有问题请联系我。T&& 右值引用 std::move 右值引用出现之前我们只能…

HDU5977-Garden of Eden-树分治+FWT

题目描述 When God made the first man, he put him on a beautiful garden, the Garden of Eden. Here Adam lived with all animals. God gave Adam eternal life. But Adam was lonely in the garden, so God made Eve. When Adam was asleep one night, God took a rib fro…

C++11新特性学习

https://blog.csdn.net/tennysonsky/article/details/778170481、什么是C11C11标准为C编程语言的第三个官方标准&#xff0c;正式名叫ISO/IEC 14882:2011 - Information technology -- Programming languages -- C。在正式标准发布前&#xff0c;原名C0x。它将取代C标准第二版I…

C++ override 关键字用法

override关键字作用&#xff1a; 如果派生类在虚函数声明时使用了override描述符&#xff0c;那么该函数必须重载其基类中的同名函数&#xff0c;否则代码将无法通过编译。举例子说明struct Base {virtual void Turing() 0;virtual void Dijkstra() 0;virtual void VNeumann…

Gym - 101981I-MagicPotion-最大流

题目描述 There are n heroes and m monsters living in an island. The monsters became very vicious these days, so the heroes decided to diminish the monsters in the island. However, the i-th hero can only kill one monster belonging to the set Mi. Joe, the st…

c++仿函数 functor

https://www.cnblogs.com/decade-dnbc66/p/5347088.html内容整理自国外C教材先考虑一个简单的例子&#xff1a;假设有一个vector<string>&#xff0c;你的任务是统计长度小于5的string的个数&#xff0c;如果使用count_if函数的话&#xff0c;你的代码可能长成这样&#…

HDU4812-D Tree-树分治

题目描述 There is a skyscraping tree standing on the playground of Nanjing University of Science and Technology. On each branch of the tree is an integer (The tree can be treated as a connected graph with N vertices, while each branch can be treated as a v…

成为C++高手之实战项目

https://blog.csdn.net/niu_gao/article/details/51458721 在内存中模拟出一副牌&#xff0c;然后模拟洗牌&#xff0c;发牌等动作。 流程是这样的&#xff1a;构建一副牌保存到一个数组中—洗牌—创建玩家—向玩家发牌–输出每个玩家的牌。 #include <stdio.h> #include…

C++中String类的实现

https://www.cnblogs.com/zhizhan/p/4876093.html原文&#xff1a;http://noalgo.info/382.html String是C中的重要类型&#xff0c;程序员在C面试中经常会遇到关于String的细节问题&#xff0c;甚至要求当场实现这个类。只是由于时间关系&#xff0c;可能只要求实现构造函数、…

Ubuntu软件更新失败

刚安装好Ubuntu以后需要将系统的软件都更新一下&#xff0c;但是遇到一个问题就是下载仓库信息失败&#xff0c;大概是这个样子的错误&#xff1a; 经国遇到这样的问题可以试一下下面这个命令&#xff1a; sudo rm -rf /var/lib/apt/lists/* sudo apt-get update参考网址&…

getsockname函数与getpeername函数的使用

https://www.tuicool.com/articles/V3Aveygetsockname和getpeername函数 getsockname函数用于获取与某个套接字关联的本地协议地址 getpeername函数用于获取与某个套接字关联的外地协议地址 定义如下&#xff1a;[cpp] view plaincopy#include<sys/socket.h> int gets…

Ubuntu根目录空间不足

自己在固态硬盘上安装的Ubuntu&#xff0c;结果只用了一天就显示磁盘空间不足。查看空间以后发现Ubuntu自己安装的时候默认给根目录分配的是10GB,然而我们下载的软件以及环境等一般都安装在根目录空间下&#xff0c;尤其是/usr目录所占的空间很大。 不得已我在网上查找了如何给…

Linux命令【一】基本命令

shell命令和bash命令相同&#xff0c;指的是命令解析器 快捷键 history 所有的历史命令ctrl P 向上滚动命令 ctrl N 向下滚动命令 ctrlB将光标向前移动 ctrlF将光标向后移动 ctrlA移动到命令行头部 ctrlE移动到命令行尾部 光标删除操作&#xff1a;删除光标前面字符ctrlh或…

The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement

http://www.jb51.net/article/119654.htmThe MySQL server is running with the --skip-grant-tables option so it cannot execute this statement 意思貌似MYSQL还运行在 --skip-grant-tables模式&#xff0c;如何让他回到原来的模式 第一种方法&#xff1a;原来在mysql.ini文…

解决Ubuntu“下载额外数据文件失败 ttf-mscorefonts-installer”的问题

参考博客&#xff1a;传送门 下载[ttf-mscorefonts-installer.zip](https://pan.baidu.com/s/1i5rLfMH) 密码: h76g 然后解压到下载的目录&#xff0c;在当前目录执行命令&#xff1a; sudo dpkg-reconfigure ttf-mscorefonts-installer这条命令手动指定文件夹的位置,重新配置…

【C语言】单链表的相关热点面试题(包括:从尾到头打印,逆置,冒泡,寻找中间节点,倒数k节点)

https://blog.csdn.net/hanjing_1995/article/details/51539599从尾到头打印单链表[cpp] view plaincopyvoid FromTailToHeadPrint(SListNode*& head) { stack<SListNode*> s; SListNode* cur head; while (cur) { s.push(cur); …

Linux命令【二】终端+Vim

需要先安装net-tools ifconfig eth0 网卡&#xff0c;硬件地址为MAC 地址&#xff0c;网卡编号&#xff0c;绝对不会重复 lo 回环地址 测试两台主机之间能否通信&#xff1a;ping IP或域名 [-c 4//回馈四条信息 -i//每隔多少秒回馈一次] 得到域名对应的IPnslookup 域名得到域…

Linux如何将文件中内容放到粘贴板上

没有找到如何在vim中将内容复制到粘贴板上&#xff0c;只找到了使用另一个软件进行操作。 首先安装xsel sudo apt-get install xsel # 将剪切板中的内容输出到文件 echo $(xsel --clipboard) >> a.txt# 将文件的内容复制到剪切板 cat a.txt | xsel --clipboard

【C语言】str类与men库函数的实现(如:strcpy,strcmp,strstr,strcat,memmove,memcpy)

https://blog.csdn.net/hanjing_1995/article/details/51539583strcpy拷贝源字符串到子字符串&#xff0c;包括‘\0’。代码实现&#xff1a;[cpp] view plaincopychar* strcpy(char* dst,const char* src) { assert(src); char* ret dst; while (*src) …