中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

利用C++怎么實現(xiàn)一個迭代器功能-創(chuàng)新互聯(lián)

這篇文章給大家介紹利用C++ 怎么實現(xiàn)一個迭代器功能,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

目前成都創(chuàng)新互聯(lián)公司已為成百上千的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)絡(luò)空間、網(wǎng)站托管運營、企業(yè)網(wǎng)站設(shè)計、長島網(wǎng)站維護等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

STL中的迭代器


迭代器模式是一種經(jīng)典的設(shè)計模式,而STL的迭代器實現(xiàn)用到了模板的一些特性和技能,在這里稍微介紹一下

下面是STL中結(jié)構(gòu)體iterator的定義,這么定義是給后面的算法多態(tài)和萃取時(具體見書中介紹)使用的。

其中的_Category 和_Ty 沒有默認值,需要自己給參數(shù)的。

_Ty就是元素的類型

template<class _Category,
 class _Ty,
 class _Diff = ptrdiff_t,
 class _Pointer = _Ty *,
 class _Reference = _Ty&>
 struct iterator
 { // base type for iterator classes
 typedef _Category iterator_category;
 typedef _Ty value_type;
 typedef _Diff difference_type;
 typedef _Diff distance_type; // retained
 typedef _Pointer pointer;
 typedef _Reference reference;
 };

而_Category是迭代器的類型,主要有以下幾種

// ITERATOR STUFF (from <iterator>)
// ITERATOR TAGS (from <iterator>)
struct input_iterator_tag //只讀
 { // identifying tag for input iterators
 };
struct _Mutable_iterator_tag //只寫
 { // identifying tag for mutable iterators
 };
struct output_iterator_tag //只寫
 : _Mutable_iterator_tag
 { // identifying tag for output iterators
 };
struct forward_iterator_tag //前向移動
 : input_iterator_tag, _Mutable_iterator_tag
 { // identifying tag for forward iterators
 };
struct bidirectional_iterator_tag //可雙向移動
 : forward_iterator_tag
 { // identifying tag for bidirectional iterators
 };
struct random_access_iterator_tag //隨機讀寫
 : bidirectional_iterator_tag
 { // identifying tag for random-access iterators
 };
//...

自定義迭代器

我希望迭代器有以下操作:*,++。另外還想要通過迭代器調(diào)用count_if函數(shù)。那看一下count_if都用到哪些操作符吧

// TEMPLATE FUNCTION count_if
template<class _InIt,
 class _Pr> inline
 typename iterator_traits<_InIt>::difference_type
 _Count_if(_InIt _First, _InIt _Last, _Pr _Pred)
 { // count elements satisfying _Pred
 typename iterator_traits<_InIt>::difference_type _Count = 0;
 for (; _First != _Last; ++_First)
 if (_Pred(*_First))
  ++_Count;
 return (_Count);
 }

可以看到用到了++,!=,*。所以我們的迭代器需要把這些都給實現(xiàn)了。代碼很簡單:

#include<iterator>
template<class T>
class MyIterator : public iterator<input_iterator_tag, T>{
 public:
 MyIterator(T* p){
  _ptr = p;
 }
 //賦值
 MyIterator& operator = (const MyIterator &iter)
 {
 _ptr = iter._ptr;
 }
 //不等于
 bool operator != (const MyIterator &iter)
 {
 return _ptr!= iter._ptr;
 }
 //等于
 bool operator == (const MyIterator &iter)
 {
 return _ptr == iter._ptr;
 }
 //前綴自加
 MyIterator& operator ++ ()
 {
 _ptr++;
 return *this;
 }
 //后綴自加
 MyIterator operator ++ (int)
 {
 MyIterator tmp= *this;
 _ptr++;
 return tmp;
 }
 //取值
 T& operator * ()
 {
 return *_ptr;
 }
 private:
 T* _ptr;//實際的內(nèi)容指針,通過該指針跟容器連接
};

自定義容器

下面給出個簡單的數(shù)組容器,實現(xiàn)了數(shù)組的基本操作。并把剛剛定義的迭代器內(nèi)置了

template<class T>
class myVector{
public:
 typedef MyIterator<T> iterator;//所有類型迭代器用同一個名字,便于寫出更通用的代碼
 myVector(){
 _selfElems = new T[32];
 _count = 32;
 init();
 }
 myVector(int n){
 _selfElems = new T[n];
 _count = n;
 init();
 }
 void init(){
 memset(_selfElems, 0, sizeof(T)* _count);
 }
 //常用接口
 T& operator[](int i){
 return _selfElems[i];
 }
 iterator begin(){
 return iterator(_selfElems);
 }
 iterator end(){
 return iterator(_selfElems + _count);
 }
 int size() const {
 return _count;
 }
private:
 T* _selfElems;
 int _count;
};

##測試

定義一個vector和自定容器myVector,用迭代器去訪問,并通過迭代器使用conunt_if函數(shù),可以看到用法完全一樣

bool eq_10(int k){
 return k == 10;
}
int main(){
 //自定義類型
 myVector<int> mv(10);
 mv[3] = 10; mv[9] = 10;
 myVector<int>::iterator it = mv.begin();
 cout <<"mv:"<<endl;
 while (it != mv.end()){
 cout << *(it++) << " ";
 }
 cout << endl;
 cout << count_if(mv.begin(), mv.end(), eq_10) << endl;
 //STL 容器
 vector<int> v(10,0);
 v[3] = 10; v[9] = 10;
 vector<int>::iterator it1 = v.begin();
 cout << "v:" << endl;
 while (it1 != v.end()){
 cout << *(it1++) << " ";
 }
 cout << endl;
 cout << count_if(mv.begin(), mv.end(), eq_10) << endl;
 getchar();
 return 0;

總結(jié)和思考

所以簡單來說,如果想要定義自己容器的迭代器并想通過迭代器調(diào)用STL的算法函數(shù)的話。首先繼承iteroter,然后實現(xiàn)必要的操作符即可。不過具體的算法函數(shù)對迭代器類型是有要求的,這個需要自己把握。

在這個簡單的示例里面,直接用myVector的指針(mv._ptr)也是可以調(diào)用count_if的,因為STL通過模板偏特化技術(shù)使得迭代器也支持原生指針。不過既然把訪問元素都放到迭代器中了,我們就可以對所有的容器用統(tǒng)一的方式訪問了,而不用暴露每個容器的細節(jié)(myVector::_ptr):

//T為某種迭代器
template<class T>
void display(T it, T end){
 T it1 = it;
 while (it1 != end){
 cout << *(it1++) << " ";
 }
 cout << endl;
 cout << count_if(it,end, eq_10) << endl;
}
int main(){
 //自定義類型
 myVector<int> mv(10);
 mv[3] = 10; mv[9] = 10;
 //STL 容器
 vector<int> v(10, 0);
 v[3] = 10; v[9] = 10;
 //vector 和 myVector底層實現(xiàn)有很大區(qū)別,但是可用同一個函數(shù)做遍歷等操作
 display(mv.begin(), mv.end());
 display(v.begin(), v.end());
 getchar();
 return 0;
}

迭代器賦予了容器更多的功能和通用性

補充知識:C++ 自定義迭代器(實現(xiàn)++遞增兩格)

//效果每次迭代器加移動兩格

#pragma once
//MyIterator.h
#include <iterator>
#include <exception>
template<typename Container>
class MyIterator :public std::iterator<std::random_access_iterator_tag, typename Container::value_type>
{
protected:
  Container& container;
  typename Container::iterator pos;
public:
  explicit MyIterator(Container& c) :container(c), pos(c.begin()){}
  MyIterator(const MyIterator& rhs) :container(rhs.container),pos(rhs.pos) {}
  MyIterator& operator =(const MyIterator& rhs)
  {
    throw_ex(rhs.container);
    pos = rhs.pos;
    return *this;
  }
  //--等就省略了...
  MyIterator& operator ++()
  {
    auto tmp = container.end() - 1;
    if (pos == tmp)
      ++pos;
    else
      pos += 2;
    return *this;
  }
  bool operator ==(const MyIterator& rhs)const
  {
    try
    {
      if (&rhs.container == &container)
        return pos == rhs.pos;
      else
      {
        throw exception("對象錯誤");
      }
    }
      catch (exception &e)
      {
        cout << e.what();
        exit(EXIT_FAILURE);
      }
    }
bool operator !=(const MyIterator& rhs)const
{
  return !(*this == rhs);
}
typename Container::value_type & operator *()
{
      return *pos;
}
void begin()
{
  pos = container.begin();
}
void end()
{
  pos = container.end();
}
private:
  void throw_ex(const Container& c)
  {
    try
    {
      if (&c == &container)
        return;
      else
        throw exception("Copy 構(gòu)造失敗");
    }
    catch (exception &e)
    {
      cout << e.what();
      exit(EXIT_FAILURE);
    }
  }
};
//無法使用或添加vector<T> vec 成員函數(shù)vec.begin()或全局函數(shù)begin(vec)
//我們做個假冒的全局函數(shù) start(vec) over(vec)
template<typename Container>
MyIterator<Container> start(Container& c)
{
    MyIterator<Container> mi(c);
    mi.begin();
    return mi;
}
template<typename Container>
MyIterator<Container> over(Container & c)
{
    MyIterator<Container> mi(c);
    mi.end();
    return mi;
}

//main.cpp

#include <iostream>
#include <vector>
#include "MyIterator.h"
#include <list>
using namespace std;
//因繼承了iterator<std::random_access_iterator_tag,Container::value_type>才擁有此特性
template<typename Iterator>
void printIterator(const Iterator &It)
{
  cout << typeid(typename iterator_traits<Iterator>::iterator_category).name() << endl;
}
int main()
{
  vector<int> coll{ 1,2,3,4,5,6,7,8,9,10 };
  MyIterator<decltype(coll)> myit(coll);
  printIterator(myit);
  for (; myit != over(coll); ++myit)
  {
    cout << *myit << ends;
  }
  system("pause");
  return 0;
}

效果:

利用C++ 怎么實現(xiàn)一個迭代器功能

關(guān)于利用C++ 怎么實現(xiàn)一個迭代器功能就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

網(wǎng)頁標題:利用C++怎么實現(xiàn)一個迭代器功能-創(chuàng)新互聯(lián)
本文地址:http://www.rwnh.cn/article48/ddceep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、品牌網(wǎng)站設(shè)計、網(wǎng)站改版、用戶體驗Google、企業(yè)網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)
县级市| 静乐县| 嘉荫县| 莱州市| 陆川县| 永兴县| 遂溪县| 乐昌市| 牙克石市| 天长市| 屏东市| 铁岭市| 永德县| 沅陵县| 嘉定区| 丹凤县| 师宗县| 新郑市| 紫金县| 乌什县| 弥勒县| 盖州市| 全州县| 罗甸县| 荆州市| 乐山市| 辽源市| 东兴市| 邳州市| 谢通门县| 定结县| 宣武区| 石河子市| 江陵县| 永丰县| 宜良县| 广水市| 尉氏县| 洞头县| 延寿县| 灵寿县|