模仿std::vector写线性表的几点感想
数据结构还是很早之前学的了,当时才刚学过C语言,实现得都很简单,最近决定重新打牢基础,于是重新开始实现书上的数据结构和算法。
模仿C++ Primer的StrVec以及std::vector,使用模板类+allocater分配内存,遵循“三/五原则”,期间遇到了几个小问题,记录下。
1、unsigned和signed的比较:
在实现insert操作时,写了个私有方法去把数组index处开始的元素向后移动n位。分两种情况处理,一种是容量不够需要重新分配内存,另一种是容量足够,直接向后移动。
前一种分配内存空间后可以直接用uninitialized_copy搬运元素,也可以用Allocater::construct构造元素。而后一种是在原先分配的内存上重新构造元素,因此要注意先更新的位置就不要再使用。

如上图,把index为1开始的元素向后移动1位。如果从前往后移动,第一次就会改动位置2处的元素,但是位置2处的元素需要移动到位置3处,这样就造成了错误。
因此需要从后移动,我之前的代码就是 for (size_t i = count - 1; i >= index; --i)
乍看之下没有问题,但是在index为0的时候就出错了。size_t是unsigned int,假如是为0再自减,会变成unsigned包含的最大的数,具体原因我之前写过一篇博客说过。
所以我把size_t改成了int,代码变成 for (int i = count - 1; i >= index; --i)
但是依旧出错,调试发现:int i = -1; unsigned index = 0; 那么i > index为true。其实编译器已经把问题提出来了:warning c4018 : signed/unsigned mismatch
signed和unsigned进行比较时会都转换成unsigned比较,也就是说虽然i自减成了负数,但是进行比较时会被强制转换为unsigned,这个循环依旧是个死循环。
解决方法:
1、把index强制转换为int,这样就会是signed之间比较;
2、改成for (int i = 0; i < count - index; ++i)然后改变循环体内关于i的部分,这样比较麻烦,而且i不能直接体现出表达的意义。
2、类模板中定义友元函数
如果友元函数的定义在类中则没有什么问题,如果要写在类的外部就有点麻烦。以下面代码为例。
template <typename T>
class SqList; template <typename T>
std::ostream &operator<<(std::ostream &, const SqList<T> &); template <typename T>
class SqList
{
friend std::ostream &operator<< <T>(std::ostream &, const SqList<T> &);
// ...
} template <typename T>
std::ostream &operator<< (std::ostream &os, const SqList<T> &lst)
{
for (auto iter = lst.begin(); iter != lst.end(); ++iter)
os << *iter << ' ';
return os;
}
首先,友元函数需要在类之前进行声明,这点跟普通类的友元函数不同(具体原因需要复习下模板的知识,暂不深究)。而由于友元函数会用到类模板作为参数,所以必须再对类模板进行前置声明。
其次,模板类的友元函数本质上是个函数模板,因此在类模板中进行友元声明时在函数名后用模板参数实例化,否则就会出现经典的外部链接错误error LINK 2019,因为会判断类外部的函数实现(operator<<)并不是对类内的operator<<的实现,所以在调用这个友元方法时编译器找不到定义。
模仿std::vector写线性表的几点感想的更多相关文章
- [C++]使用vector描述线性表定义及基本操作
#ifndef VECTORLIST_H #define VECTORLIST_H #include<iostream> #include"linearlist.h" ...
- C++编程练习(1)----“实现简单的线性表的顺序存储结构“
线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素. 故可以用数组来实现顺序存储结构. 用C++编写的利用数组实现简单的读取.插入和删除功能的线性表. #include< ...
- 随机排序std::vector,扑克牌,麻将类尤其合用
有些需要重新对std::vector对象重新排序,特别是游戏,例如说:扑克牌,麻将,抽奖等,C++标准已经为std::vector写好了随机排序的方式,这里做个笔记: #include <alg ...
- JAVA中的数据结构——集合类(线性表:Vector、Stack、LinkedList、set接口;键值对:Hashtable、Map接口<HashMap类、TreeMap类>)
Java的集合可以分为两种,第一种是以数组为代表的线性表,基类是Collection:第二种是以Hashtable为代表的键值对. ... 线性表,基类是Collection: 数组类: person ...
- 已知长度为n的线性表采用顺序结构,写一算法删除该线性表中所有值为item的元素
/** * @author:(LiberHome) * @date:Created in 2019/2/27 23:34 * @description: * @version:$ */ /*已知长度为 ...
- 数据结构(1) 第一天 算法时间复杂度、线性表介绍、动态数组搭建(仿Vector)、单向链表搭建、企业链表思路
01 数据结构基本概念_大O表示法 无论n是多少都执行三个具体步骤 执行了12步 O(12)=>O(1) O(n) log 2 N = log c N / log c N (相当于两个对数进行了 ...
- Java数据结构之线性表
从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...
- [置顶] ※数据结构※→☆线性表结构(queue)☆============循环队列 顺序存储结构(queue circular sequence)(十)
循环队列 为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量.存储在其中的队列称为循环队列(Circular Queue). ...
- c++转载系列 std::vector模板库用法介绍
来源:http://blog.csdn.net/phoebin/article/details/3864590 介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作 ...
随机推荐
- js字符串操作方法
1.字符方法: str.charAt(): 可以访问字符串中特定的字符,可以接受0至字符串长度-1的数字作为参数,返回该位置下的字符,如果参数超出该范围,返回空字符串,如果没有参数,返回位置为0的字符 ...
- 【hive】子查询
hive中是不支持子查询的 但是并不意味这不支持in 或者 not in in 或者not in 后边是定值的话是支持的 但是接定制是可以的 例如 select id from table not i ...
- 【hive】解析json格式字符串
(1)解析json中的单个属性 get_json_object(json_str,’$.xxx’/‘$[xxx]’) get_json_object函数第一个参数填写json对象变量(string) ...
- EPANET中的typedef使用
struct Floatlist /* Element of list of floats */{ double value; struct Floatlist *next;};typ ...
- Git的三种区域
Git的区域分为 工作区.缓存区.本地仓库区 我们先看一张图 GitTest是我本地的一个仓库, 其中GitTest目录就是我们的工作区,但不包括.git这个目录 而.git这个目录就是本 ...
- C#学习历程(六)[ref 关键字的使用]
ref 关键字的使用 ref 关键字通过引用(而非值)传递参数. 通过引用传递的效果是,对所调用方法中的参数进行的任何更改都反映在调用方法中. 例如,如果调用方传递本地变量表达式或数组元素访问表达式, ...
- QT中Qtableview视图表格中点击表头进行排序
用QT写了一个小工具,主要是对Excel中大量的数据进行计算和显示. 写了有一段时间,然后断断续续的做一些修改和完善. 因为要显示的数据有多列,很自然的会想到要能够对显示的数据进行排序.如果直接操作m ...
- gridview 后台增加列
BoundField field1 = null; field1 = new BoundField(); //实例化 field1.HeaderText = "序号";field ...
- *SCM-MANAGERtomcat寄宿使用
采用的部署方式 TomCat 一个端口下部署多个 Application供不同部门使用 初始部署详参见 SCM-MANAGER 博文 日常使用添加部门操作步骤 从“D:\tomcat\webapps” ...
- 20165210 《网络对抗技术》week1 exp0 kali安装与配置
20165210 <网络对抗技术>week1 exp0 kali安装与配置 1. 安装过程: 从kali官网上下载如下图所示: 下载完成后打开VMware 点击创建新的虚拟机 弹出新虚拟机 ...