模仿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包含的最大的数,具体原因我之前写过一篇博客说过。

C语言的补码表示和unsigned及signed的转换

所以我把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<<的实现,所以在调用这个友元方法时编译器找不到定义。

时间: 2024-11-13 09:39:01

模仿std::vector写线性表的几点感想的相关文章

[C++]使用vector描述线性表定义及基本操作

#ifndef VECTORLIST_H #define VECTORLIST_H #include<iostream> #include"linearlist.h" #include<vector> #include<myexceptions.h> using namespace std; template<class T> class vectorList : public linearList<T> { public:

线性表Vector

线性表 Vector #ifndef SJTU_VECTOR_HPP #define SJTU_VECTOR_HPP #include <cstddef> #include <cstring> #include <string> #include <cstdlib> #include <vector> #include <climits> #include <cstddef> namespace sjtu { class

Structure.List 线性表 - 专业|程序|作业|项目|Code|代写|C|C++|Java|Matlab|C#|JS|留学生

线性表 包含顺序链表,单链表,双链表,双向循环链表的实现 代码下载链接: Structure.List =============================================================================================== 国内TOP5高校计算机工程师个人代写 QQ联系专业高效原创 QQ(24小时在线): 1926742804 如紧急可发送资料到[email protected]

【C/C++学院】0903-Boost/线性表/哈希存储

boost模板库与线性表 Boost的安装 使用boost,首先需要进行的环境配置. #include <iostream> #include <string> #include<boost/array.hpp>//区别 using namespace std; void main() { boost::array<int, 10> myarray = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; boost::array<in

Java数据结构之线性表

从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的几张,我们将会分别讲解这几种数据结构,主要也是通过Java代码的方式来讲解相应的数据结构. 今天要讲解的是:Java线性结构 Java数据结构之线性结构 说到线性结构的话,我们可以根据其实现方式分为三类: 1)顺序结构的线性表 2)链式结构的线性表 3)栈和队列的线性表 1.顺序结构的线性表    

【线性表2】线性表的顺序实现:顺序表

顺序表简介 特点:使用一组地址连续的存储单元依次存储表中的数据元素,常见的就是使用数组去实现. 表中逻辑相邻的数据元素,在物理内存上也相邻. 顺序表中的任意数据元素都可随机访问,是一种支持随机访问,长度自动动态调整的线性表结构. 优点:访问表中的元素很快,时间复杂度为O(1) 缺点:插入,删除元素需要移动大量的元素,时间复杂度为O(n) . 因此如果我们在编程中需要这样一种线性表数据结构:构造后对元素的访问操作很频繁,而很少进行增,删等元素位置的调整操作,那么就可以考虑使用顺序表. 代码实现 #

数据结构_线性表的顺序表示和链式表示

/********************************************************************************************************************/ 声明: (1)*.h文件是代码声明, *.cpp文件是代码实现; (2)一般头文件的内容有: ①类型声明; ②函数声明; ③枚举; ④常量; ⑤宏 (3)以下说明是为了方便代码文件的管理而设定的一些规则, 以后代码都会按照此规则编写: 1)Pubuse.h 是几

数据结构代码整理(线性表,栈,串,二叉树)。。持续更新中。。。

//线性表 #include <cstdio> #include <cstring> #include <iostream> #include <cstdlib> using namespace std; ///都用c语言写的 ///建议从主函数开始看 int sequence_map[100005]; ///顺序表的数组 int total_sequence=0,total_list=0; ///定义两个全局变量用来计算顺序表与链表长度,初始值为0 str

双向链式线性表(模板实现)

线性表(List):零个或者多个数据元素的有限序列. 线性表的存储结构大约分为三种:1,顺序存储结构 2,链式存储结构 3,静态链表. 顺序存储结构的线性表是由数组实现的,由于C++不支持变长数组,所以顺序存储结构的线性表在定义时就指定了长度,这是一个很大的问题.譬如说,一个顺序存储结构的线性表的长度为10000,我们写程序用到了这个线性表,但是只往表里添加了十几个数据,这显然对空间造成了极大的浪费.所以说,这种结构的线性表并适用于实际的应用. 链式存储结构的线性表实现了空间的动态分配,这一概念