Vector迭代器实现

2023-11-16

实现数组的迭代器

实现内容:
1:使用C++语言实现一个长度可扩充的数组结构(要求使用class实现),不能直接使用vector等现成的数据结构。
2:要求实现为可以用于不同数据类型的数组结构(并不是说同一个对象需要存储多种类型的数据),建议使用template实现
3:为实现的数组结构添加迭代器(iterator) 接口(包括Iterator 和 ConstIterator)

代码:

#include <iostream>
#include <memory.h>
#include <assert.h>

using namespace std;

template <typename T>
class CArrayIterator;

template <typename T>
class CArrayConstIterator;

template <typename T>
class CArray
{
public:
    typedef T Element;
    typedef CArrayIterator<T> Iterator;
    typedef CArrayConstIterator<T> ConstIterator;

public:
    CArray():_size(0),_cap(0) {_buff=NULL;}
	CArray(const CArray &rhs)
	{
		_size=rhs._size;
		_cap=rhs._cap;
		_buff=new Element[_cap];
		for(int i=0;i<rhs._size;++i)
			_buff[i]=rhs._buff[i];
	}
    ~CArray() 
	{
	    //这里不可以加delete,否则会内存超限
	    /*
		if(_buff != NULL)
			delete[] _buff;
		*/
		_buff=NULL;
		_size=0;
		_cap=0;
	}

public:
    int capacity() const
    {
        return _cap;
    }
    int size() const
    {
        return _size;
    }

    void recap(int cap)
	{
		if (cap == _cap){return;}
		
		Element *buff = new Element[cap];
		_cap = cap;
		_size = cap < _size ? cap : _size;
		
		memcpy(buff, _buff, _size * sizeof(Element));
        delete[] _buff;

        _buff = buff;
	}

    Element &at(int index)
    {
        return _buff[index];
    }
    Element at(int index) const
    {
        return _buff[index];
    }

    void append(Element element)
	{
		if(_size == _cap)
			recap(_cap+1);
		_buff[_size++] = element;
	}
    void insert(int index, Element element)
	{
		if(_size == _cap)
		recap(_cap+1);
		
		for (int i = _size; i > index; --i)
		{
			_buff[i] = _buff[i - 1];
		}
		_buff[index] = element;
		_size += 1;
	}

    void copy(const CArray &rhs)
	{
		if(_cap < rhs._cap)
			recap(rhs._cap);
		
		memcpy(_buff, rhs._buff, rhs._size * sizeof(Element));
	    _size = rhs._size;
	}

    bool compare(const CArray &rhs) const
	{
		if (rhs._size != _size){return false;}
		return memcmp(_buff, rhs._buff, _size) == 0;
	}

	Iterator begin(){return Iterator(_buff);}
	Iterator end(){return Iterator(_buff+_size);}
	ConstIterator begin() const{return ConstIterator(_buff);}
	ConstIterator end()const {return ConstIterator(_buff+_size);}

private:
    void _check_capacity(int minimal)
	{
		if(_cap<minimal)
			this->recap(minimal);
	}
    Element *_buff;//数据
    int _size;//元素个数
    int _cap;//容量
};

template <typename T>
class CArrayIterator
{

public:
    CArrayIterator() {}
	CArrayIterator(T *current){_current=current;}
	CArrayIterator(const CArrayIterator &rhs){_current=rhs._current;}
    ~CArrayIterator()
	{
	    /*
		if(_current!=NULL)
			delete _current;
		*/
		_current=NULL;
	}

public:
    //实现所需要的操作符重载函数
	CArrayIterator operator++(){_current++;return *this;}
	CArrayIterator operator++(int)
	{
		CArrayIterator tmp(*this);
		++(*this);
		return tmp;
	}
	bool operator!=(const CArrayIterator rhs){return this->_current!=rhs._current;}
	bool operator==(const CArrayIterator rhs){return this->_current==rhs._current;}
	T& operator*() const{return *_current;}
	T* operator->() const{return _current;}

protected:
    T *_current;
    friend class CArray<T>;
};

template <class T>
class CArrayConstIterator
{
public:
    CArrayConstIterator() {_current=NULL;}
	CArrayConstIterator(T *current){_current=current;}
	CArrayConstIterator(const CArrayConstIterator &rhs){_current=rhs._current;}
    ~CArrayConstIterator()
	{
		/*
		if(_current!=NULL)
			delete _current;
		*/
		_current=NULL;
	}

public:
    //实现所需要的操作符重载函数
	CArrayConstIterator operator++(){_current++;return *this;}
	CArrayConstIterator operator++(int)
	{
		CArrayConstIterator tmp(*this);
		++(*this);
		return tmp;
	}
	bool operator!=(const CArrayConstIterator rhs)const{return this->_current!=rhs._current;}
	bool operator==(const CArrayConstIterator rhs)const{return this->_current==rhs._current;}
	T& operator*() const{return *_current;}
	T* operator->() const{return _current;}

protected:
    T *_current;
    friend class CArray<T>;
};

附上测试代码:

template <typename T>
class Obj
{
public:
    Obj(){};
    Obj(int val) : data(val){};
    ~Obj(){};

public:
    T data;

private:
    template <typename Tp>
    friend std::ostream &operator<<(std::ostream &os, const Obj<Tp> &obj);
};

template <typename Tp>
std::ostream &operator<<(std::ostream &os, const Obj<Tp> &obj)
{
    os << obj.data;
    return os;
}

int main(int argc, char const *argv[])
{
    CArray<int> array;
    // 不再需要initial,但应该有正确的初始化
    // array_initial(array);
    array.recap(10);
    assert(array.capacity() == 10);
    //
    for (int i = 0; i < 20; ++i)
    {
        array.append(i);
    }
    assert(array.size() == 20);
    for (int i = 0; i < array.size(); ++i)
    {
        assert(array.at(i) == i);
    }
    //
    CArray<int> array2, array3;
    // array_initial(array2);
    // array_initial(array3);
    array2.copy(array);
    assert(array.compare(array2) == true);
    array3.copy(array);
    assert(array.compare(array3) == true);
    //
    array2.insert(2, 3);
    assert(array.compare(array2) == false);
    //
    array3.at(2) = 5;
    assert(array.compare(array3) == false);
    //
	for (CArray<int>::Iterator it = array.begin(); it != array.end(); ++it)
    {
        std::cout << *it << " ";
        (*it) = (*it) + 10;
    }
    std::cout << std::endl;
    for (CArray<int>::Iterator it = array.begin(); it != array.end();)
    {
        std::cout << *(it++) << " ";
    }
    std::cout << std::endl;
    const CArray<int> tmp(array);

    for (CArray<int>::ConstIterator it = tmp.begin(); it != tmp.end(); ++it)
    {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
    CArray<Obj<int>> obj_arr;
    for (CArray<int>::ConstIterator it = tmp.begin(); it != tmp.end();)
    {
        obj_arr.append(Obj<int>(*it));
        std::cout << *(it++) << " ";
    }
    std::cout << std::endl;
    for (CArray<Obj<int>>::Iterator it = obj_arr.begin(); it != obj_arr.end(); ++it)
    {
        std::cout << (*it) << " ";
    }
    std::cout << std::endl;
    for (CArray<Obj<int>>::Iterator it = obj_arr.begin(); it != obj_arr.end(); ++it)
    {
        std::cout << it->data << " ";
    }
    std::cout << std::endl;
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vector迭代器实现 的相关文章

  • 删除文件的最后 10 个字符

    我想删除文件的最后 10 个字符 说一个字符串 hello i am a c learner 是文件内的数据 我只是希望该文件是 hello i am a 文件的最后 10 个字符 即字符串 c learner 应在文件内消除 解决方案 将
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat

随机推荐

  • el-table page翻页后保留所勾选项。

    项目场景 el table 翻页后保留所勾选项 问题描述 例如 刚开始还在使用原始的方式进行翻页回显 因为翻页之后 点选时selection会出现undefined 所以这里需要进行判断 这里可以通过判断选择selection中有没有row
  • Ubuntu 16.04下编译Caffe-CPU版最可靠完整的版本!!!!(踩了所有的坑,试了几乎所有方法)

    Ubuntu 16 04下编译Caffe CPU版最可靠完整的版本 踩了所有的坑 试了几乎所有方法 Introduction 我踩的坑 各种软件包的版本 GCC版本的确定与调整 一 相关依赖包的安装 二 caffe的下载 三 protobu
  • 文盘Rust -- FFI 浅尝

    rust FFI 是rust与其他语言互调的桥梁 通过FFI rust 可以有效继承 C 语言的历史资产 本期通过几个例子来聊聊rust与C 语言交互的具体步骤 场景一 调用C代码 创建工程 cargo new bin ffi sample
  • 【DFS和BFS习题集+分类总结】(更新至2023.1.1)(17788字)

    目录 第一题 八皇后 dfs 路径输出 前驱版 第一题的补充练习 N皇后 dfs 打表 第二题 自然数的拆分 第三题 图的遍历 BFS和DFS 第四题 fire net dfs 第五题 nightmare 可以走回头路的DFS 第六题 滑雪
  • 【漏洞修复】Diffie-Hellman Key Agreement Protocol 资源管理错误漏洞(CVE-2002-20001)

    CANCANJUN Diffie Hellman Key Agreement Protocol 资源管理错误漏洞 CVE 2002 20001 概述 漏洞名称 Diffie Hellman Key Agreement Protocol 资源
  • springMVC、freemarker页面半自动静态化

    1 请求 do的URL时直接生成对应的 htm文件 并将请求转发到该htm文件 2 自由控制某个页面是否需要静态化 如果看图不懂的呢 说白了这个中技术就是 java对象 ftl模型 输出html视图 1 在sprinMVC中 MVC框架中的
  • 【数据分析师自学系列-MySQL】创建新表create table、create table as、create table like的区别

    数据分析师自学系列 MySQL 创建新表create table create table as create table like的区别 1 create table 基本创建新表方式 格式如下 create table 新表名 列名1
  • java反射机制创建对象实现:java 深度拷贝 -超完美

    java反射机制创建对象实现 java 深度拷贝 超完美 自己做的 下面 package aop public class Student private String name private int age public String
  • 乘法逆元之欧几里得和扩展欧几里得

    乘法逆元 文章目录 乘法逆元 一 模运算的性质 二 除法的模运算 1 除法模运算 2 解决除法模运算问题 三 乘法逆元 1 定义 2 逆元是干什么的呢 四 求解逆元 1 费马小定理 2 扩展欧几里得 exgcd 1 裴蜀定理 2 exgcd
  • C语言问题:0xC0000005: 写入位置 0xFFFFFFCC 时发生访问冲突。

    最近系统地开始学习C语言 在使用VS2019中用scanf s为一串字符串赋值时 发生了错误 错误如下 0x7837EF8C ucrtbased dll 处 位于 Project2 exe 中 引发的异常 0xC0000005 写入位置 0
  • typora+阿里云OSS+PicGO进行图床设置

    typora 阿里云OSS PicGO进行图床设置 文章目录 typora 阿里云OSS PicGO进行图床设置 前言 crystal ball 一 阿里云OSS设置 satellite 1 进入 阿里云OSS官网 https www al
  • 解决刷新tagsview首页消失问题和引入path报错问题

    我的tagsview功能是用nuoyi源码 如果你的代码有tagsview功能直接找这个文件 如果没有这个功能可以参考nuoyi源码 重点参考以下文件 或者参考 通俗易懂 vue实现tagsview标签导航栏切换菜单功能 详细注释 都能看的
  • 原型聚类&&密度聚类&&层次聚类

    1 原型聚类 原型聚类算法假设聚类结构可以通过一组原型刻画 通常算法先会对原型进行初始化 然后对原型进行迭代更新求解 不同的原型表示和不同的求解方式会产生不同的算法 下面主要介绍三种典型的原型聚类算法 k 均值 学习向量量化 和 高斯混合聚
  • mybatis和spring的集成方法

    集成mybatis和spring 需要的步骤 1 新建maven项目 2 加入maven依赖 在pom xml加依赖 1 加入spring依赖
  • vscode 无法远程调试 xdebug

    launch json version 0 2 0 configurations name Listen for XDebug type php request launch port 9001 该端口不要和php fpm端口相同 path
  • Redis Streams做股票行情MQ?

    redis作为内存数据库 大多时候都是作为缓存来使用 但是因为有pub sub的存在 所以也可以做MQ来使用 做为MQ 它有两个严重的问题 1 无法持久化 2 没有ack机制 redis pub sub是一个要即时消费的MQ 如果消费晚了
  • 序列式容器

    容器的概观与分类 常用的数据结构不外乎array 数组 list 链表 tree 树 stack 堆栈 queue 队列 hash table 散列表 set 集合 map 映射 等等 根据 数据再容器中的排列 特性 这些数据结构分为序列式
  • 华为云云耀云服务器L实例评测

    大家好 我是雄雄 欢迎关注微信公众号 雄雄的小课堂 目录 前言 效果图 购买云耀云服务器L实例 重置密码 放开端口 远程连接 安装云监控面板 进入监控面板 前言 有幸参与了华为云云耀云服务器L实例的评测名额 借着评测 顺便教给大家一项技能
  • 多视图聚类(multi-view clustering)简介

    多视图聚类 目前大概有以下几种 多视图k means聚类 多视图谱聚类 多视图图聚类 多视图子空间聚类 multi view subspace clustering 深度学习多视图聚类 deep multi view clustering
  • Vector迭代器实现

    实现数组的迭代器 实现内容 1 使用C 语言实现一个长度可扩充的数组结构 要求使用class实现 不能直接使用vector等现成的数据结构 2 要求实现为可以用于不同数据类型的数组结构 并不是说同一个对象需要存储多种类型的数据 建议使用te