CSDN博客

img sixsavage

Boost源码简析系列——Array(2)

发表于2004/3/23 10:10:00  1069人阅读

Boost源码简析系列——Array(2)

1.         赋值函数等

                         //...

         static size_type size() { return N; }
        static bool empty() { return false; }
        static size_type max_size() { return N; }
        enum { static_size = N };
        void swap (array<T,N>& y) {
            std::swap_ranges(begin(),end(),y.begin());
        }
        const T* data() const { return elems; }
        template <typename T2>
        array<T,N>& operator= (const array<T2,N>& rhs) {
            std::copy(rhs.begin(),rhs.end(), begin());
            return *this;
        }
        void assign (const T& value)
        {
            std::fill_n(begin(),size(),value);
        }
      private:
        static void rangecheck (size_type i) {
            if (i >= size()) { throw std::range_error("array"); }
       }
        //...
size()
array容器能容元素的数量。
empty()
容器是否为空?
max_size()
容器最多能容元素的数量。
swap()
交换两个容器元素序列中的相应元素。
data()
返回容器中存放元素的数组首地址。
operator=()
重载赋值函数。
assign()
用一个值取代一段元素序列中元素的值。
rangecheck()
检查是否超范围访问容器。
 
在这一组函数中,有几个问题我不知道代码的编写者是怎么想的。
首先是,既然boost::array是静态数组的代替,那么对于定义好的boost::array对象能存放的元素个数也就定下来,不能修改,那么在这里就没有必要提供两个member function:
size()和max_size()。何况这两个函数除了名字不同以外,其他的操作都是一样的。也许Josuttis是给以后这个类的扩展预留了空间吧。
其次是,empty()函数也让人浮想联翩,看起来好像是判断容器是否为空的方法,但是仔细一看实现代码,却是直接返回了一个false。
然后是,data(),居然直接返回的是容器中第一个元素的地址。我想,用户用指针直接访问元素并不是Josuttis愿意看到的。
最后是,rangecheck()函数,对是否访问位置溢出的检查,只注意了上溢,没有注意到有可能下溢。
我在这里并不是指责Josuttis没有程序员应用的严谨,这些看似有漏洞的地方,是作者为了以后扩展功能故意留下的。
剩下的三个函数,都是赋值函数:
swap(),把A容器中的全部元素与B容器中的相应位置的元素相互交换。A是调用swap()函数。用了STL中标准算法swap_ranges()。
operator=(),用B容器给A容器赋值,A容器调用operator=()函数。
assign(),用一个指定的值代替容器中一段元素序列中的元素的值。用了标准算法fill_n()。
这组函数使用,见例2。
2.                        比较函数
//...
template<class T, std::size_t N>
    bool operator== (const array<T,N>& x, const array<T,N>& y) {
        return std::equal(x.begin(), x.end(), y.begin());
    }
    template<class T, std::size_t N>
    bool operator< (const array<T,N>& x, const array<T,N>& y) {
        return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
    }
    template<class T, std::size_t N>
    bool operator!= (const array<T,N>& x, const array<T,N>& y) {
        return !(x==y);
    }
    template<class T, std::size_t N>
    bool operator> (const array<T,N>& x, const array<T,N>& y) {
        return y<x;
    }
    template<class T, std::size_t N>
    bool operator<= (const array<T,N>& x, const array<T,N>& y) {
        return !(y<x);
    }
    template<class T, std::size_t N>
    bool operator>= (const array<T,N>& x, const array<T,N>& y) {
        return !(x<y);
    }
    template<class T, std::size_t N>
    inline void swap (array<T,N>& x, array<T,N>& y) {
        x.swap(y);
    }
         //...
operator==()
比较两个容器中元素序列是否相等。
operator<()
比较两个容器中元素序列按字典排序哪个小。
operator!=()
判断两个容器中元素序列是否不等。
operator>()
比较两个容器中元素序列按字典排序哪个大。
operator<=()
比较两个容器,前者是否小于等于后者。
operator>=()
比较两个容器,前者是否大于等于后者。
swap()

static的形式提供了swap的功能。

这组比较函数,是基于C++标准库的标准算法做出的。
operator==()中为了比较两个序列中相应元素是否相等,用了标准算法中的equal()。如果两个序列对应元素相同则真。
operator<()中为了比较两个序列按字典序谁大谁小,前者小为真。用了lexicograhpic_compare()。
其他的函数,又是基于==和<很简单就做出来了。实际的使用,参考例2。
上面就是,boost::array提供给我们的所有资源及其源码。从这些源码我们可以看出来,技术上是依赖了C++的标准库算法。
提供给了用户大多数的STL容器接口,让用户可以很方便的访问,比较容器中的元素。通过at()访问元素还可以避免超范围访问。
从效率上来看,几乎所有的member function的实现都非常简单,编译器把她们都看成是inline函数,比起普通数组来说,效率并没有下降。
所以总的说来,这个boost::array是优秀的静态数组容器类。完全可以作为普通数组的替代。下面两个例子,具体实现了对array类的使用方式。
//例2
#include <iostream>
#include <string>
#include <boost/array.hpp>
#include <stdlib.h>
int main(void)
    {
        boost::array<std::string,4> seasons = {
              { "spring", "summer", "autumn", "winter" }
              };
        std::cout<<seasons[2]<<'/n';
        std::cout<<seasons.at(2)<<'/n';
        std::cout<<seasons.front()<<'/n';
        std::cout<<seasons.back()<<'/n';
        std::cout<<seasons.size()<<'/n';
        std::cout<<seasons.max_size()<<'/n';
        boost::array<std::string,4> _seasons = {
                       { "spring", "summer", "autumn"}};
        if(seasons == _seasons)
        {
            std::cout<<"equality."<<'/n';
        }
        else if(_seasons < seasons)
        {
            std::cout<<"_seasons is more smaller."<<'/n';
        }
        else
        {
            std::cout<<"seasons is more smaller."<<'/n';
        }
              system("pause");
              return 0;
    }
同例1一样,例2也在Dev-C++上编译通过,而vc告诉我有语法错误,我晕。
参考文献:
boost::array英文文档;
Bjarne Stroustrup 《The C++ Programming Language,3rd edition》。
                                        
                                        sixsavage(野人)于March 22, 2004作
                                                 sixsavage@yahoo.com
                                                 

 

0 0

相关博文

我的热门文章

img
取 消
img