第二十七课再论智能指针(上)(代码片段)

wanmeishenghuo wanmeishenghuo     2022-12-31     464

关键词:

思考:

  使用智能指针替换单链表LinkLIst中的原生指针是否可行?

将LinkList.h中的Node指针全部改成智能指针:

  1 #ifndef LINKLIST_H
  2 #define LINKLIST_H
  3 
  4 #include "List.h"
  5 #include "Exception.h"
  6 #include "SmartPointer.h"
  7 
  8 namespace DTLib
  9 
 10 
 11 template < typename T >
 12 class LinkList : public List<T>
 13 
 14 protected:
 15     struct Node : public Object
 16     
 17         T value;
 18         SmartPointer<Node> next;
 19     ;
 20 
 21     mutable struct : public Object
 22     
 23         char reserved[sizeof(T)];
 24         SmartPointer<Node> next;
 25     m_header;
 26 
 27     int m_length;
 28     int m_step;
 29     SmartPointer<Node> m_current;
 30 
 31     Node* position(int i) const    //  O(n)
 32     
 33         //Node* ret = reinterpret_cast<Node*>(&m_header);
 34         SmartPointer<Node> ret = reinterpret_cast<Node*>(&m_header);
 35 
 36         for(int p = 0; p < i; p++)
 37         
 38             ret = ret->next;
 39         
 40 
 41         return ret.get();
 42     
 43 
 44     virtual Node* create()
 45     
 46         return new Node();
 47     
 48 
 49     virtual void destroy(Node* pn)
 50     
 51         delete pn;
 52     
 53 
 54 public:
 55     LinkList()
 56     
 57         m_header.next = NULL;
 58         m_length = 0;
 59         m_step = 1;
 60         m_current = NULL;
 61     
 62 
 63     bool insert(const T& e)
 64     
 65         return insert(m_length, e);
 66     
 67 
 68     bool insert(int i, const T& e)   // O(n)
 69     
 70         bool ret = ((0 <= i) && (i <= m_length));
 71 
 72         if( ret )
 73         
 74             Node* node = create();
 75 
 76             if( node != NULL )
 77             
 78                 Node* current = position(i);
 79 
 80                 node->value = e;
 81                 node->next = current->next;
 82                 current->next = node;
 83 
 84                 m_length++;
 85             
 86             else
 87             
 88                 THROW_EXCEPTION(NoEnoughMemoryException, "No memery to insert new element...");
 89             
 90         
 91 
 92         return ret;
 93     
 94 
 95     bool remove(int i)   // O(n)
 96     
 97         bool ret = ((0 <= i) && (i < m_length));
 98 
 99         if( ret )
100         
101             SmartPointer<Node> current = position(i);
102 
103             SmartPointer<Node> toDel = current->next;
104 
105             if( m_current == toDel )
106             
107                 m_current = toDel->next;
108             
109 
110             current->next = toDel->next;
111 
112             m_length--;
113 
114             // destroy(toDel);
115 
116         
117 
118         return ret;
119     
120 
121     bool set(int i, const T& e)   //  O(n)
122     
123         bool ret = ((0 <= i) && (i < m_length));
124 
125         if( ret )
126         
127             position(i)->next->value = e;
128         
129 
130         return ret;
131     
132 
133     T get(int i) const
134     
135         T ret;
136 
137         if( get(i, ret) )
138         
139             return ret;
140         
141         else
142         
143             THROW_EXCEPTION(IndexOutOfBoundsException, "Invalid parameter i to get element ...");
144         
145 
146         return ret;
147     
148 
149     bool get(int i, T& e) const    // O(n)
150     
151         bool ret = ((0 <= i) && (i < m_length));
152 
153         if( ret )
154         
155             e = position(i)->next->value;
156         
157 
158         return ret;
159     
160 
161     int find(const T& e) const    //  O(n)
162     
163         int ret = -1;
164         int i = 0;
165 
166         SmartPointer<Node> node = m_header.next;
167 
168         //while( node )
169         while( node.isNull() )
170         
171             if( node->value == e )
172             
173                 ret = i;
174                 break;
175             
176             else
177             
178                 node = node->next;
179                 i++;
180             
181         
182 
183         return ret;
184     
185 
186     int length() const   // O(1)
187     
188         return m_length;
189     
190 
191     void clear()    //  O(n)
192     
193         //while( m_header.next )
194         while( m_header.next.isNull() )
195         
196             //Node* toDel = m_header.next;
197             SmartPointer<Node> toDel = m_header.next;
198 
199             m_header.next = toDel->next;
200 
201             m_length--;
202 
203             // destroy(toDel);
204         
205 
206         // m_length = 0;
207     
208 
209     bool move(int i, int step = 1)
210     
211         bool ret = (0 <= i) && (i < m_length) && (step > 0);
212 
213         if( ret )
214         
215             m_current = position(i)->next;
216             m_step = step;
217         
218 
219         return ret;
220     
221 
222     bool end()
223     
224         //return (m_current == NULL);
225         return m_current.isNull();
226     
227 
228     T current()
229     
230         if( !end() )
231         
232             return m_current->value;
233         
234         else
235         
236             THROW_EXCEPTION(InvalidOperationException, "No value at current position ...");
237         
238     
239 
240     bool next()   //每次移动step步
241     
242         int i = 0;
243 
244         while((i < m_step) && !end())
245         
246             m_current = m_current->next;
247             i++;
248         
249 
250         return (i == m_step);
251     
252 
253     ~LinkList()   //  O(n)
254     
255         clear();
256     
257 ;
258 
259 
260 
261 #endif // LINKLIST_H

测试程序如下:

 1 #include <iostream>
 2 #include "LinkList.h"
 3 
 4 using namespace std;
 5 using namespace DTLib;
 6 
 7 
 8 int main()
 9 
10     LinkList<int> list;
11 
12     for(int i = 0; i < list.length(); i++)
13     
14         list.insert(i);
15     
16 
17     for(list.move(0); !list.end(); list.next())
18     
19         cout << list.current() << endl;
20     
21 
22     return 0;
23 

运行结果如下:

技术分享图片

程序直接崩溃了。

技术分享图片

 

 我们的SmartPointer设计中,一片堆空间最多只能由一个指针标识,但是我们设计的和遍历有关的函数,例如move、end、current、next,在遍历时一片堆空间会由多个指针指向,所以程序崩溃了。

改进方案:

技术分享图片

我们需要创建一个中间类pointer,并且它还有两个子类。

SharedPointer支持一片堆空间由多个指针指向,也支持自动释放。

在设计上做了改动,所以SmartPointer也得做改动。

技术分享图片

pointer类中的析构函数是纯虚函数,因为pointer是一个抽象父类,需要由子类继承才能生成对象。

技术分享图片

Object的析构函数就是纯虚的,所以pointer中就没有必要再写一遍了。

只要pointer没有实现自己的析构函数,那么它就还是一个抽象类。

 

第28课再论智能指针(下)

1.SharedPointer的设计(1)使用类模板,通过计数机制标识堆内存(2)堆内存被指向时,refCount++(3)指针被置空时:refCount—(4)当refCount==0时,释放堆内存2.计数机制原理剖析 3.SharedPointer类的声明template<typenameT>classSharedP... 查看详情

第二十七课

第一单元语法部分      Vて行く Vて来る「行く、来る」有方向性。以某物为参照物、接在「Vて」形式后面,表示完成V动作后进行方向性移动。   Vていく   ①表示移动时的状态。&ldq... 查看详情

再论智能指针(上)(代码片段)

0.引言:目的:使用智能指针替代LinkList中的原生的指针,限制:但是我们的智能指针设定了只能单个指针指向某一片堆空间 1. 智能指针的继承层次结构(1)Pointer是智能指针的抽象父类(模板)  ①纯虚析构函数:virt... 查看详情

c++从青铜到王者第二十五篇:c++智能指针(代码片段)

系列文章目录文章目录系列文章目录前言一、常见面试题1.malloc/free和new/delete的区别2.内存泄漏1.内存泄漏概念与危害2.内存泄漏分类(了解)3.如何检测内存泄漏(了解)4.如何避免内存泄漏5.如何一次在堆上申请4G... 查看详情

再论智能指针(上)

替换成SmartPointer:测试:直接崩溃比如:智能指针军规之一:一片空间只能一个指针指着…先把之前SmartPointer替换的地方再改回来…SmartPointer.h中直接删除一下函数代码,因为父类中已经实现了:打印:... 查看详情

mysql基础第二十七天,使用游标(代码片段)

游标使用游标callpressorders();//使用游标创建游标createprocedureprecessorders()begindeclaredonebooleandefault0;declaretdecimala(10,2);declareoint;declareordernumberscursorforselectorder_numfromorders;declarecontinue 查看详情

第二十七天-网络通信协议tcpudp缓冲区(代码片段)

  1.网络通信协议  osi七层模型:按照分工不同把互联网协议从逻辑上划分了层级   socket层 2.理解socket:  Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是... 查看详情

每日算法&面试题,大厂特训二十八天——第二十七天(函数)(代码片段)

目录标题导读算法特训二十八天面试题点击直接资料领取导读肥友们为了更好的去帮助新同学适应算法和面试题,最近我们开始进行专项突击一步一步来。上一期我们完成了动态规划二十一天现在我们进行下一项对各类算法... 查看详情

c++从青铜到王者第二十七篇:特殊类设计(代码片段)

系列文章目录文章目录系列文章目录前言一、请设计一个类,只能在堆上创建对象二、请设计一个类,只能在栈上创建对象三、请设计一个类,不能被拷贝四、请设计一个类,不能被继承五、请设计一个类,... 查看详情

第二十七节:安全存储机密程序(代码片段)

原文:第二十七节:安全存储机密程序一.基本概念1.背景  通常我们将AppSecret和数据库连接字符串存储在配置文件中,web.config或appsettings.json,配置文件都需要提交到SVN和git上,对于一些开发者自己用而不需要提交的数据, ... 查看详情

(94)wangdao.com_第二十七天_键盘事件(代码片段)

键盘事件键盘事件由用户击打键盘触发主要有keydown、keyup、keypress三个事件,它们都继承了KeyboardEvent接口。keydown     按下键时触发keyup    松开键时触发keypress    按下有值的键时触... 查看详情

stm32f429第二十七篇之dma实验详解(代码片段)

文章目录前言结构体Instance(实例)Init(初始化结构体)Lock(锁)State(状态)XferCpltCallback(传输完成回调函数)XferHalfCpltCallback(传输完成一半回调函数)XferM1CpltCallback(内存1传输完成回调函数)XferM1HalfCpltCallback(内存1传输一半回调函数)XferErrorCa... 查看详情

第七十七课最小生成树(kruskal)(代码片段)

          添加kruskal算法: 1#ifndefGRAPH_H2#defineGRAPH_H34#include"Object.h"5#include"SharedPointer.h"6#include"Array.h"7#include"DynamicArray.h"8#i 查看详情

再论智能指针(下)

测试:小结 查看详情

第五十七课树中属性操作的实现(代码片段)

  添加count函数:1#ifndefGTREE_H2#defineGTREE_H34#include"Tree.h"5#include"GTreeNode.h"6#include"Exception.h"78namespaceDTLib91011template<typenameT>12classGTree:publicTree<T>1314pr 查看详情

第十七届全国大学生智能车竞赛航天智慧物流创意组-第二次线上技术培训(代码片段)

   全国大学生智能汽车竞赛-航天智慧物流创意组,以工业智慧物流为主题,以无人驾驶技术在工业上的应用为基础,围绕人工智能领域典型传感器的使用、操作、编程、调试等内容,考察选手对当下热门的运... 查看详情

第六十七课经典问题解析五

一、问题一:编写一个函数判断一个变量是不是指针1、拾遗(1)、c++中仍然支持C语言中的可变参数函数(2)、c++编译器的匹配调用优先级:重载函数-------->函数模板--------->变参函数2、思路(1)、将变量分为两类:指针VS... 查看详情

-考研第二十七周总结-

-考研第二十七周总结-【本周完成】背书上的单词这周时间总被挤掉手机背单词每天高数看书+做了第五剩下的和第六章的题看完了,也进行了一章的复习做题英语跟着唐叔阅读的进行做题代码题做了6道(其中包括我去... 查看详情