c++ stl的迭代器部分功能可以这样实现

前言

本文首先写了我理解的迭代器的部分功能,然后写如何实现这些功能,纯属是个人理解和实现,并不代表stl的迭代器就是那样实现的。本人还未阅读stl源码,不知道stl是如何实现的。为此特别说明,我不希望误导stl学习者。

我理解的c++ stl容器迭代器的部分功能

功能1:是对容器元素的指针

星号运算符

假设vector<int> list中某个元素list[2]的指针是point,迭代器器是iter。
我们可以这样使用指针:

int value=*point;
*point=3;    //这会导致list[2]=3;

我们可以像指针一样使用迭代器:

int value=*iter; 
*iter=3;     //这会导致list[2]=3;

->运算符

定义一个简单的类

class demo
{
	public:
	int v1;
	int v2;
}

假设vector<demo> list2的一个元素list2[2]是{1,2}。它的指针是point,它的迭代器是iter。
我们可以这样使用指针

int v1=point->v1;
point->v1=3;   //list2[2].v1=3;

我们可以以同样的方式使用迭代器

int v1-iter->v1;
point->v1=3;   //list2[2]=3;

功能1总结

我们可以把迭代器理解为指向某个元素的指针,然后可以像使用指针一样使用这个迭代器。

功能2:容器元素的成员的子集

树是节点的容器。节点是树的元素。节点有很多成员,有很多成员我们需要提供给用户,有些成员需要对用户屏蔽。通过迭代器就可以做到这点。用户从来不直接访问具体节点,他们最多只能获取节点对应的迭代器。迭代器里面有节点部分成员的引用。访问或者修改迭代器的成员,实际上就是访问和修改节点的成员。节点中要对用户屏蔽的成员,我们不要让他出现在迭代器成员里面即可。

功能3:容器元素的成员的访问权限

有时我们希望用户能够访问节点的部分信息,这部分信息中,又有一部分希望用户只能读不能写,一部分允许用户读和写。迭代器可以实现这样的功能。用户从来不能直接访问容器元素,他们只能访问容器元素的迭代器。我们在迭代器把只能读不能写的节点成员引用加上const。用户就不能修改了,但仍然可读。

功能4:容器的成员函数可以通过迭代器获取元素的地址,但用户不能

用户交给容器一个元素的迭代器,希望容器对这个元素做一些操作,由于迭代器里面是没有节点的全部信息的(迭代器是容器元素成员的子集),可能导致某些动作无法完成。幸运的是,容器可以通过迭代器获取它所指向的元素的地址。这个是个特殊权限。因为我们不希望用户可以这样做,不希望用户获取节点的全部信息。

对上面4个功能的实现

直接上代码,后面有对代码的解读和说明:

#include <iostream>

using namespace std;
class my_node;  //前部申明
class rb_tree;

class my_iterator
{
    public:
    const int &key;
    int &value;

    my_iterator(int& _key,int& _value):key(_key),value(_value)
    {
    }
    my_iterator* operator->()
    {
        return this;
    }
    int& operator*()
    {
        return value;
    }
    private:
    my_node *node;
    friend rb_tree;
};
class my_node
{
    public:
    int key;
    int value;
    my_node *left;
    my_node *right;
    my_iterator iter;
    my_node():iter(key,value){key=1;value=1;}
};


class rb_tree
{
public:
    void rb_delete(my_iterator iter)
    {
        my_node *node=iter->node; //通过迭代器获取迭代器对应的节点。只有容器的方法可以获取。其他地方获取容器方法是不行的。
    }
    

};

int main()
{
    my_node a;
    my_iterator aiter=a.iter;
    cout<<"通过迭代器获取节点的key:"<<aiter->key<<endl;
    //aiter.key=2;    //若取消注释,编译不通过,因为只能通过迭代器读key,不能修改key
    //my_node *ap=aiter->node;  //若取消注释,编译不通过,因为只有rb_tree的成员函数可以通过迭代器获取节点。
    cout<<"通过迭代器获取节点的value:"<<aiter->value<<endl;
    *aiter=2;//通过迭代器重载的*运算符修改节点的value值。
    cout<<"通过迭代器重载的*运算符修改节点的value值:"<<a.value<<endl;
    aiter->value=3;
    cout<<"通过迭代器修改节点的value值:"<<a.value<<endl;
}

前部申明

由于节点类中有一个迭代器成员,所以迭代器类必须在节点类前定义。又由于迭代器类中有一个节点类对象指针。所以必须在迭代器类前面对节点类做前部申明。前部申明之后,类申明之前,该类只能以指针或者引用的方式出现。

迭代器的类成员是节点类部分成员的引用

这样,主函数修改迭代器的类成员,实际上就是修改节点。
迭代器中的key前面加了const,使得用户只能读key,不能修改key。

由于把引用作为类成员,所以该类不能有缺省的构造函数,必须自己实现构造函数,并在初始化列表中,完成对引用类成员的初始化,而且,构造函数的参数也必须是引用类型。否则,编译会报错。

重载->运算符

为了使得迭代器能够像指针一样使用,重载了->运算符,这是一个单目运算符,返回指向对象本身的指针。

重载*运算符

这里返回的是节点 value字段的引用,使得迭代器像指向节点value字段的指针一样。

my_node指针private

节点迭代器与节点一一对应,体现在迭代器里面有一个node的指针。设置为private,使得用户不能通过迭代器对象获取节点指针。但又申明tree为友元。这样树(节点的容器)就可以访问迭代器的private成员,就可以过去迭代器对应的节点的指针了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值