国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【c++手撕STL】之迭代器

這篇具有很好參考價(jià)值的文章主要介紹了【c++手撕STL】之迭代器。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

迭代器定義

在C++ STL(Standard Template Library,標(biāo)準(zhǔn)模板庫)中,迭代器是一個(gè)非常重要的組成部分。迭代器像是一個(gè)指針,負(fù)責(zé)在容器的元素之間移動(dòng),并且能夠訪問到容器的元素。

C++ STL提供了幾種類型的迭代器,每種迭代器都有它獨(dú)特的功能和特性:

  1. 輸入迭代器(Input Iterators):只讀不寫,只能單向移動(dòng)(自增++)。
  2. 輸出迭代器(Output Iterators):只寫不讀,只能單向移動(dòng)(自增++)。
  3. 前向迭代器(Forward Iterators):可讀寫,只能單向移動(dòng)(自增++)。
  4. 雙向迭代器(Bidirectional Iterators):可讀寫,可以雙向移動(dòng)(自增++,自減–)。
  5. 隨機(jī)訪問迭代器(Random Access Iterators):可讀寫,支持全部迭代器運(yùn)算??梢赃M(jìn)行任意跳躍的訪問。

在使用時(shí),可以像操作指針一樣通過*操作符來操作迭代器訪問元素,例如*iter。STL中的標(biāo)準(zhǔn)容器像是vector、listmap等都支持迭代器,你可以創(chuàng)建相應(yīng)的迭代器來進(jìn)行遍歷操作。

例如:

std::vector<int> vec = {1, 2, 3, 4, 5};
for(std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
    std::cout << *it << std::endl;
}

在這個(gè)例子中,vec.begin()返回一個(gè)指向vector開始的迭代器,vec.end()返回一個(gè)指向vector結(jié)尾后一位置的迭代器。這是STL的一種慣用方式,end()迭代器并不指向任何元素,它用來提供一種方便的判斷遍歷是否結(jié)束的條件。

迭代器的種類

輸入迭代器 提供對(duì)數(shù)據(jù)的只讀訪問 支持++、==、!=
輸出迭代器 提供對(duì)數(shù)據(jù)的只寫訪問 支持++
前向迭代器 提供讀寫操作,并能將迭代器向前推進(jìn) 支持++、==、!=
雙向迭代器 提供讀寫操作,并能將迭代器向前推進(jìn)也能向后推進(jìn) 支持++、–
隨機(jī)訪問迭代器 提供讀寫操作,并能任意位置訪問容器,是功能最強(qiáng)的迭代器 支持++、–、[n]、-n、>、<、>=、<=

手撕代碼

類型信息定義

#ifndef __TYPE_TRAITS_HPP__
#define __TYPE_TRAITS_HPP__

// 這個(gè)頭文件用于提取類型信息

#include <type_traits>
#include <utility>

namespace Stl
{
    template <class T, T v>
    struct m_integral_constant
    {
        static constexpr T value = v;
    };
    template <bool b>
    using m_bool_constant = m_integral_constant<bool, b>;

    typedef m_bool_constant<true> m_true_type;
    typedef m_bool_constant<false> m_false_type;

    // is_pair

    // --- forward declaration end

    template <class T>
    struct is_pair : Stl::m_false_type
    {
    };

    template <class T1, class T2>
    struct is_pair<std::pair<T1, T2>> : Stl::m_true_type
    {
    };
}

#endif /* __TYPE_TRAITS_HPP__ */

迭代器設(shè)計(jì)

#ifndef __ITERATOR_HPP__
#define __ITERATOR_HPP__

// 這個(gè)頭文件用于迭代器設(shè)計(jì),包含了一些模板結(jié)構(gòu)體與全局函數(shù),

#include <cstddef>
#include "type_traits.hpp"

namespace Stl
{

    // 五種迭代器類型
    // 輸入迭代器
    struct input_iterator_tag
    {
    };
    // 輸出迭代器
    struct output_iterator_tag
    {
    };
    // 前向迭代器
    struct forward_iterator_tag : public input_iterator_tag
    {
    };
    // 雙向迭代器
    struct bidirectional_iterator_tag : public forward_iterator_tag
    {
    };
    // 隨機(jī)訪問迭代器
    struct random_access_iterator_tag : public bidirectional_iterator_tag
    {
    };

    // iterator 模板
    template <class Category, class T, class Distance = ptrdiff_t,
              class Pointer = T *, class Reference = T &>
    struct iterator
    {
        typedef Category iterator_category; // 迭代器類型標(biāo)簽
        typedef T value_type;               // 所指對(duì)象類型
        typedef Pointer pointer;            // 指針類型
        typedef Reference reference;        // 引用類型
        typedef Distance difference_type;   // 兩個(gè)迭代器之間距離的類型,通常是ptrdiff_t
    };

    // iterator traits
    // 檢查是否有迭代器類型標(biāo)簽
    template <class T>
    struct has_iterator_cat
    {
    private:
        struct two
        {
            char a;
            char b;
        };
        template <class U>
        static two test(...);
        template <class U>
        static char test(typename U::iterator_category * = 0);

    public:
        static const bool value = sizeof(test<T>(0)) == sizeof(char);
    };

    template <class Iterator, bool>
    struct iterator_traits_impl
    {
    };

    template <class Iterator>
    struct iterator_traits_impl<Iterator, true>
    {
        typedef typename Iterator::iterator_category iterator_category;
        typedef typename Iterator::value_type value_type;
        typedef typename Iterator::pointer pointer;
        typedef typename Iterator::reference reference;
        typedef typename Iterator::difference_type difference_type;
    };

    template <class Iterator, bool>
    struct iterator_traits_helper
    {
    };

    template <class Iterator>
    struct iterator_traits_helper<Iterator, true>
        : public iterator_traits_impl<Iterator,
                                      std::is_convertible<typename Iterator::iterator_category, input_iterator_tag>::value ||
                                          std::is_convertible<typename Iterator::iterator_category, output_iterator_tag>::value>
    {
    };

    // 萃取迭代器的特性
    template <class Iterator>
    struct iterator_traits
        : public iterator_traits_helper<Iterator, has_iterator_cat<Iterator>::value>
    {
    };

    // 針對(duì)原生指針的偏特化版本
    // 輔助函數(shù)來訪問迭代器的屬性
    template <class T>
    struct iterator_traits<T *>
    {
        typedef random_access_iterator_tag iterator_category; // 獲取迭代器類型標(biāo)簽
        typedef T value_type;                                 // 獲取所指對(duì)象類型
        typedef T *pointer;                                   // 獲取指針類型
        typedef T &reference;                                 // 獲取引用類型
        typedef ptrdiff_t difference_type;                    // 獲取距離類型
    };

    template <class T>
    struct iterator_traits<const T *>
    {
        typedef random_access_iterator_tag iterator_category;
        typedef T value_type;
        typedef const T *pointer;
        typedef const T &reference;
        typedef ptrdiff_t difference_type;
    };

    // 檢查迭代器類型標(biāo)簽是否匹配
    template <class T, class U, bool = has_iterator_cat<iterator_traits<T>>::value>
    struct has_iterator_cat_of
        : public m_bool_constant<std::is_convertible<
              typename iterator_traits<T>::iterator_category, U>::value>
    {
    };

    // 萃取某種迭代器
    template <class T, class U>
    struct has_iterator_cat_of<T, U, false> : public m_false_type
    {
    };

    // 檢查是否為輸入迭代器
    template <class Iter>
    struct is_input_iterator : public has_iterator_cat_of<Iter, input_iterator_tag>
    {
    };

    // 檢查是否為輸出迭代器
    template <class Iter>
    struct is_output_iterator : public has_iterator_cat_of<Iter, output_iterator_tag>
    {
    };

    // 檢查是否為前向迭代器
    template <class Iter>
    struct is_forward_iterator : public has_iterator_cat_of<Iter, forward_iterator_tag>
    {
    };

    // 檢查是否為雙向迭代器
    template <class Iter>
    struct is_bidirectional_iterator : public has_iterator_cat_of<Iter, bidirectional_iterator_tag>
    {
    };

    // 檢查是否為隨機(jī)訪問迭代器
    template <class Iter>
    struct is_random_access_iterator : public has_iterator_cat_of<Iter, random_access_iterator_tag>
    {
    };

    // 檢查是否為迭代器(輸入或輸出)
    template <class Iterator>
    struct is_iterator : public m_bool_constant<is_input_iterator<Iterator>::value ||
                                                is_output_iterator<Iterator>::value>
    {
    };

    // 萃取某個(gè)迭代器的 category
    template <class Iterator>
    typename iterator_traits<Iterator>::iterator_category
    iterator_category(const Iterator &)
    {
        typedef typename iterator_traits<Iterator>::iterator_category Category;
        return Category();
    }

    // 萃取某個(gè)迭代器的 distance_type
    template <class Iterator>
    typename iterator_traits<Iterator>::difference_type *
    distance_type(const Iterator &)
    {
        return static_cast<typename iterator_traits<Iterator>::difference_type *>(0);
    }

    // 萃取某個(gè)迭代器的 value_type
    template <class Iterator>
    typename iterator_traits<Iterator>::value_type *
    value_type(const Iterator &)
    {
        return static_cast<typename iterator_traits<Iterator>::value_type *>(0);
    }

    // 以下函數(shù)用于計(jì)算迭代器間的距離

    // distance 的 input_iterator_tag 的版本
    template <class InputIterator>
    typename iterator_traits<InputIterator>::difference_type
    distance_dispatch(InputIterator first, InputIterator last, input_iterator_tag)
    {
        typename iterator_traits<InputIterator>::difference_type n = 0;
        while (first != last)
        {
            ++first;
            ++n;
        }
        return n;
    }

    // distance 的 random_access_iterator_tag 的版本
    template <class RandomIter>
    typename iterator_traits<RandomIter>::difference_type
    distance_dispatch(RandomIter first, RandomIter last,
                      random_access_iterator_tag)
    {
        return last - first;
    }

    // 計(jì)算兩個(gè)迭代器之間的距離
    template <class InputIterator>
    typename iterator_traits<InputIterator>::difference_type
    distance(InputIterator first, InputIterator last)
    {
        return distance_dispatch(first, last, iterator_category(first));
    }

    // 以下函數(shù)用于讓迭代器前進(jìn) n 個(gè)距離

    // advance 的 input_iterator_tag 的版本
    template <class InputIterator, class Distance>
    void advance_dispatch(InputIterator &i, Distance n, input_iterator_tag)
    {
        while (n--)
            ++i;
    }

    // advance 的 bidirectional_iterator_tag 的版本
    template <class BidirectionalIterator, class Distance>
    void advance_dispatch(BidirectionalIterator &i, Distance n, bidirectional_iterator_tag)
    {
        if (n >= 0)
            while (n--)
                ++i;
        else
            while (n++)
                --i;
    }

    // advance 的 random_access_iterator_tag 的版本
    template <class RandomIter, class Distance>
    void advance_dispatch(RandomIter &i, Distance n, random_access_iterator_tag)
    {
        i += n;
    }

    // 將迭代器前進(jìn)指定步數(shù)
    template <class InputIterator, class Distance>
    void advance(InputIterator &i, Distance n)
    {
        advance_dispatch(i, n, iterator_category(i));
    }

    /*****************************************************************************************/

    // 模板類 : reverse_iterator
    // 代表反向迭代器,使前進(jìn)為后退,后退為前進(jìn)
    template <class Iterator>
    class reverse_iterator
    {
    private:
        Iterator current; // 記錄對(duì)應(yīng)的正向迭代器

    public:
        // 反向迭代器的五種相應(yīng)型別
        typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
        typedef typename iterator_traits<Iterator>::value_type value_type;
        typedef typename iterator_traits<Iterator>::difference_type difference_type;
        typedef typename iterator_traits<Iterator>::pointer pointer;
        typedef typename iterator_traits<Iterator>::reference reference;

        typedef Iterator iterator_type;
        typedef reverse_iterator<Iterator> self;

    public:
        // 構(gòu)造函數(shù)
        reverse_iterator() {}
        explicit reverse_iterator(iterator_type i) : current(i) {}
        reverse_iterator(const self &rhs) : current(rhs.current) {}

    public:
        // 取出對(duì)應(yīng)的正向迭代器
        iterator_type base() const
        {
            return current;
        }

        // 重載操作符
        reference operator*() const
        { // 實(shí)際對(duì)應(yīng)正向迭代器的前一個(gè)位置
            auto tmp = current;
            return *--tmp;
        }
        pointer operator->() const
        {
            return &(operator*());
        }

        // 前進(jìn)(++)變?yōu)楹笸?--)
        self &operator++()
        {
            --current;
            return *this;
        }
        self operator++(int)
        {
            self tmp = *this;
            --current;
            return tmp;
        }
        // 后退(--)變?yōu)榍斑M(jìn)(++)
        self &operator--()
        {
            ++current;
            return *this;
        }
        self operator--(int)
        {
            self tmp = *this;
            ++current;
            return tmp;
        }

        self &operator+=(difference_type n)
        {
            current -= n;
            return *this;
        }
        self operator+(difference_type n) const
        {
            return self(current - n);
        }
        self &operator-=(difference_type n)
        {
            current += n;
            return *this;
        }
        self operator-(difference_type n) const
        {
            return self(current + n);
        }

        reference operator[](difference_type n) const
        {
            return *(*this + n);
        }
    };

    // 重載 operator-
    template <class Iterator>
    typename reverse_iterator<Iterator>::difference_type
    operator-(const reverse_iterator<Iterator> &lhs,
              const reverse_iterator<Iterator> &rhs)
    {
        return rhs.base() - lhs.base();
    }

    // 重載比較操作符
    template <class Iterator>
    bool operator==(const reverse_iterator<Iterator> &lhs,
                    const reverse_iterator<Iterator> &rhs)
    {
        return lhs.base() == rhs.base();
    }

    template <class Iterator>
    bool operator<(const reverse_iterator<Iterator> &lhs,
                   const reverse_iterator<Iterator> &rhs)
    {
        return rhs.base() < lhs.base();
    }

    template <class Iterator>
    bool operator!=(const reverse_iterator<Iterator> &lhs,
                    const reverse_iterator<Iterator> &rhs)
    {
        return !(lhs == rhs);
    }

    template <class Iterator>
    bool operator>(const reverse_iterator<Iterator> &lhs,
                   const reverse_iterator<Iterator> &rhs)
    {
        return rhs < lhs;
    }

    template <class Iterator>
    bool operator<=(const reverse_iterator<Iterator> &lhs,
                    const reverse_iterator<Iterator> &rhs)
    {
        return !(rhs < lhs);
    }

    template <class Iterator>
    bool operator>=(const reverse_iterator<Iterator> &lhs,
                    const reverse_iterator<Iterator> &rhs)
    {
        return !(lhs < rhs);
    }

} // namespace mystl

#endif /* __ITERATOR_HPP__ */

源碼解析 :

定義了五個(gè)迭代器標(biāo)簽類:

  • input_iterator_tag:輸入迭代器

  • output_iterator_tag:輸出迭代器

  • forward_iterator_tag:前向迭代器,繼承自輸入迭代器

  • bidirectional_iterator_tag:雙向迭代器,繼承自前向迭代器

  • random_access_iterator_tag:隨機(jī)訪問迭代器, 繼承自雙向迭代器

定義了一個(gè)迭代器模板類 iterator,其中包含以下類型別名:

  • iterator_category:迭代器類型標(biāo)簽

  • value_type:所指對(duì)象類型

  • pointer:指針類型

  • reference:引用類型

  • difference_type:兩個(gè)迭代器之間距離的類型,通常是 ptrdiff_t

定義了一個(gè)迭代器 traits 模板類 iterator_traits,它提供一些輔助函數(shù)來訪問迭代器的屬性,例如:

  • iterator_category:獲取迭代器類型標(biāo)簽

  • value_type:獲取所指對(duì)象類型

  • pointer:獲取指針類型

  • reference:獲取引用類型

  • difference_type:獲取距離類型

定義了一些類型判斷模板類:

  • has_iterator_cat:檢查是否有迭代器類型標(biāo)簽

  • has_iterator_cat_of:檢查迭代器類型標(biāo)簽是否匹配

  • is_input_iterator:檢查是否為輸入迭代器

  • is_output_iterator:檢查是否為輸出迭代器

  • is_forward_iterator:檢查是否為前向迭代器

  • is_bidirectional_iterator:檢查是否為雙向迭代器

  • is_random_access_iterator:檢查是否為隨機(jī)訪問迭代器

  • is_iterator:檢查是否為迭代器(輸入或輸出)

定義了一些迭代器操作函數(shù):

  • distance:計(jì)算兩個(gè)迭代器之間的距離

  • advance:將迭代器前進(jìn)指定步數(shù)

  • reverse_iterator:一個(gè)反向迭代器模板類,可以通過它來實(shí)現(xiàn)反向遍歷文章來源地址http://www.zghlxwxcb.cn/news/detail-518597.html

到了這里,關(guān)于【c++手撕STL】之迭代器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • C++ STL學(xué)習(xí)之【反向迭代器】

    C++ STL學(xué)習(xí)之【反向迭代器】

    ?個(gè)人主頁: 北 海 ??所屬專欄: C++修行之路 ??每篇一句: 圖片來源 A year from now you may wish you had started today. 明年今日,你會(huì)希望此時(shí)此刻的自己已經(jīng)開始行動(dòng)了。 適配器模式是 STL 中的重要組成部分,在上一篇文章中我們學(xué)習(xí)了 容器適配器 的相關(guān)知識(shí),即 stack 與 queu

    2023年04月25日
    瀏覽(26)
  • C++ stl迭代器的理解

    首先,stl采用了泛型編程,分成了容器和算法,容器和算法之間的橋梁是迭代器,迭代器的作用是可以讓算法不區(qū)分容器來作用在數(shù)據(jù)上。 迭代器本質(zhì)上是指針,原有類型(比如int,double等)的指針也可以是迭代器,那如何讓代碼區(qū)分開他們呢? 我們可以把自定義的迭代器包

    2024年02月15日
    瀏覽(19)
  • 【C++】STL反向迭代器模擬實(shí)現(xiàn),迭代器適配器,迭代器類型簡(jiǎn)單介紹

    【C++】STL反向迭代器模擬實(shí)現(xiàn),迭代器適配器,迭代器類型簡(jiǎn)單介紹

    本篇主要講反向迭代器的模擬實(shí)現(xiàn)。 能夠加深各位對(duì)泛型的理解。 前面我那篇string介紹里面已經(jīng)提到過反向迭代器是啥了,如果點(diǎn)進(jìn)來的同學(xué)還不知道,可以看看:[string介紹](https://blog.csdn.net/m0_62782700/article/details/130796914? spm=1001.2014.3001.5501) 迭代器,可以在不暴露底層實(shí)現(xiàn)細(xì)

    2024年02月16日
    瀏覽(31)
  • 【C++】STL——反向迭代器的模擬實(shí)現(xiàn):迭代器適配器

    【C++】STL——反向迭代器的模擬實(shí)現(xiàn):迭代器適配器

    反向迭代器的使用相信大家都已經(jīng)比較熟悉了,那我們這篇文章具體講什么呢? ??,這篇文章我們重點(diǎn)來講一下 反向迭代器的模擬實(shí)現(xiàn) 。 那為什么我們之前不和正向迭代器放在一塊講呢?為什么要等到我們講完了容器適配器再來講反向迭代器的模擬實(shí)現(xiàn)呢? 那這個(gè)問題我

    2024年02月08日
    瀏覽(21)
  • 10.1 C++ STL 模板適配與迭代器

    STL(Standard Template Library)標(biāo)準(zhǔn)模板庫提供了模板適配器和迭代器等重要概念,為開發(fā)者提供了高效、靈活和方便的編程工具。模板適配器是指一組模板類或函數(shù),它們提供一種適配機(jī)制,使得現(xiàn)有的模板能夠適應(yīng)新的需求。而迭代器則是STL中的令一種重要的概念,它是一個(gè)抽

    2024年02月12日
    瀏覽(21)
  • [ C++ ] STL---反向迭代器的模擬實(shí)現(xiàn)

    [ C++ ] STL---反向迭代器的模擬實(shí)現(xiàn)

    目錄 前言: 反向迭代器簡(jiǎn)介 list反向迭代器的模擬實(shí)現(xiàn) ?反向迭代器的模擬實(shí)現(xiàn)(適配器模式) SGI版本STL反向迭代器源碼 STL庫中解引用操作與出口設(shè)計(jì) 適配list的反向迭代器 適配vector的反向迭代器 反向迭代器 是一種特殊類型的迭代器,它可以 逆向遍歷容器中的元素 ,與正向

    2024年04月15日
    瀏覽(20)
  • [C++] STL_vector 迭代器失效問題

    [C++] STL_vector 迭代器失效問題

    **迭代器的主要作用就是讓算法能夠不用關(guān)心底層數(shù)據(jù)結(jié)構(gòu),其底層實(shí)際就是一個(gè)指針,或者是對(duì)指針進(jìn)行了封裝, 比如: string的迭代器就是原生指針char ,vector的迭代器就是原生態(tài)指針T 。 因此 迭代器失效,實(shí)際就是迭代器底層對(duì)應(yīng)指針?biāo)赶虻目臻g被銷毀了,而使用一塊

    2024年02月11日
    瀏覽(24)
  • 深入探究C++中的STL:容器、迭代器與算法全解析

    Standard Template Library:標(biāo)準(zhǔn)模板庫 是一個(gè)基于泛型的C++類模板庫由Alexander Stepanov于1994年開發(fā) 其目的是為了提供一致通用和高效的數(shù)據(jù)結(jié)構(gòu)和算法,同時(shí)不限制用戶所處理的數(shù)據(jù)類型和編程范式。STL的原型最初由Andrew Koenig和其它C++專家小組進(jìn)行設(shè)計(jì)并在1995年C++標(biāo)準(zhǔn)委員會(huì)的推

    2024年02月05日
    瀏覽(100)
  • 【C++進(jìn)階(三)】STL大法--vector迭代器失效&深淺拷貝問題剖析

    【C++進(jìn)階(三)】STL大法--vector迭代器失效&深淺拷貝問題剖析

    ??博主CSDN主頁:杭電碼農(nóng)-NEO?? ? ?專欄分類:C++從入門到精通? ? ??代碼倉(cāng)庫:NEO的學(xué)習(xí)日記?? ? ??關(guān)注我??帶你學(xué)習(xí)C++ ? ???? 在閱讀本篇文章前,一定要先看前集: vector深度剖析(上) 本章重點(diǎn): 本章會(huì)重點(diǎn)講解vector迭代器失效問題 以及vector中的深淺拷貝問題 并且簡(jiǎn)

    2024年02月11日
    瀏覽(48)
  • 深入探究C++中的仿函數(shù)和迭代器——提升你的STL技能

    深入探究C++中的仿函數(shù)和迭代器——提升你的STL技能

    ??作者介紹:22級(jí)樹莓人(計(jì)算機(jī)專業(yè)),熱愛編程<目前在c++階段——目標(biāo)Windows,MySQL,Qt,數(shù)據(jù)結(jié)構(gòu)與算法,Linux,多線程,會(huì)持續(xù)分享學(xué)習(xí)成果和小項(xiàng)目的 ??作者主頁:熱愛編程的小K ??專欄鏈接:c++ ??歡迎各位→點(diǎn)贊?? + 收藏?? + 留言??? ??總結(jié):希望你看

    2023年04月24日
    瀏覽(29)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包