在实现list时所遇到的问题

简介: 在实现list时所遇到的问题

问题一:临时变量具有常性问题

在list中具体的场景:

在list中,iterator迭代器被封装成了类,iterator类中有 operator!= 这一重载函数

template <class T>
  struct __list_iterator
  {
    typedef list_node<T> Node;//结点重命名为Node
    __list_iterator(Node* node)
      :_node(node)
    {}
 
    bool operator!=( __list_iterator& it)
    {
      return _node!= it._node;
    }
    Node* _node;
  };

//iterator本质上还是一个指向Node类型的指针。

调用 operator!=

  tsj::list<int> lt1;
  lt1.push_back(1);
  lt1.push_back(2);
  lt1.push_back(3);
  tsj::list<int>::iterator it = lt1.begin();
  while (it != lt1.end())
  {
    (*it) += 1;
    cout << *it << " ";
    ++it;
  }
  cout << endl;

编译器会报错,如下:

我们不是写了!=的重载函数吗?报错说不匹配,那么只可能是参数不匹配。

实参是:lt1.end() ,形参是:__list_iterator& it

end()函数如下:

  template <class T>
  class list
  {
  public:
    typedef __list_iterator<T> iterator;
    typedef list_node<T> Node;
    list()
    {
      _head = new Node;
      _head->_prev = _head;
      _head->_next = _head;
    }
  
    iterator end()
    {
      return _head->_prev;
    }
  private:
    Node* _head;
  };

函数的返回方式有两类,一类是传值返回,一类是传引用返回。这里是传值返回。

传值返回的特点是,返回值会被寄存到一个临时对象中,函数调用结束后临时对象的内容再赋值给函数调用处,且临时对象具有常性。

那么问题找到了,end()的 返回值具有常性,而形参__list_iterator& it不具有常性。因此二者的类型不匹配,所以编译器才会报如上错误。

解决方法就是在__list_iterator& it前加上const。

问题二:单参数的构造函数支持隐式类型转换  

仍然是end()函数

_head->_prev 是指针,返回类型却是iterator,很显然二者类型不同。那他为什么可以传回去呢?上述过程等价于 __list_iterator& it=_head->_prev;上文已经提到,end()是传值返回,_head->_prev 的内容被存放到一个临时对象中,然后传递给__list_iterator& it,会调用__list_iterator中的拷贝构造函数,而拷贝构造函数的形参与_head->_prev类型一致。

对这部分总结一下:单参数的构造函数支持隐式类型转换  ,形如 __list_iterator& it=_head->_prev

看似两边的类型不同,本质上是由于=右边的类型与类的成员变量类型一致,因此会发生隐式类型转换。

相关文章
|
8月前
|
Java
初始化ArrayList的方式
初始化ArrayList的方式
58 4
|
8月前
四种解决”Arg list too long”参数列表过长的办法
这些方法都可以帮助你避免因参数列表过长而导致的错误。选择方法取决于具体情况和需求。
317 0
|
8月前
|
前端开发 Java 测试技术
把List<对象>转变<String,List<对象>>形式,k为判断的值,v为k重复的数据。
把List<对象>转变<String,List<对象>>形式,k为判断的值,v为k重复的数据。
47 0
使用BiFunction更改map的value
使用BiFunction更改map的value
47 0
|
算法 C++ 容器
<C++> list容器本质|常用接口|自定义排序规则(下)
<C++> list容器本质|常用接口|自定义排序规则
121 0
|
存储 C++ 容器
<C++> list容器本质|常用接口|自定义排序规则(上)
<C++> list容器本质|常用接口|自定义排序规则
126 0
|
存储 索引
创建List保存学生信息
创建List保存学生信息
96 0
编写一个程序,链接两个字符串字面常量,将结果保存在一个动态分配的char数组中,重写这个程序,连接两个标准string对象
编写一个程序,链接两个字符串字面常量,将结果保存在一个动态分配的char数组中,重写这个程序,连接两个标准string对象
|
存储 缓存 KVM
KVM创建存储池中报错:确认输入时未捕获的错误:constructor returned null解决
KVM创建存储池中报错:确认输入时未捕获的错误:constructor returned null解决
232 0
Python3:两个 list 一一对应,将一个 list 排序,要求另一个 list 随之排序
Python3:两个 list 一一对应,将一个 list 排序,要求另一个 list 随之排序
Python3:两个 list 一一对应,将一个 list 排序,要求另一个 list 随之排序

热门文章

最新文章