关键词:
思考:
使用智能指针替换单链表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道(其中包括我去... 查看详情