【问题标题】:Questions about an array template in C++关于 C++ 中的数组模板的问题
【发布时间】:2014-02-18 00:44:54
【问题描述】:

我正在参加一门课程,向我们介绍了一些软件模式,其中之一是迭代器模式,我们被要求用 C++ 实现它。几周前我们的教授给了我们一些示例代码,我想比我更好地理解它。首先我将发布代码:

template <class T_,std::size_t SIZE_>
class carray {
public:
typedef T_              value_type;
typedef std::size_t     size_type;
typedef T_ &            reference;
typedef T_ const &      const_reference;
typedef T_ *            pointer;
typedef T_ const *      const_pointer;
typedef T_ *            iterator;
typedef T_ const *      const_iterator;
typedef std::ptrdiff_t  difference_type;

typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

// data store
value_type data[SIZE_];

size_type   size() const { return SIZE_; }
reference operator [] ( size_type idx ) { return data[idx]; }
const_reference operator [] ( size_type idx ) const { return data[idx]; }

reverse_iterator    rbegin() { return reverse_iterator( end() ); }
reverse_iterator    rend() { return reverse_iterator( begin() ); }
const_reverse_iterator  rbegin() const { return const_reverse_iterator( end() ); }
const_reverse_iterator  rend() const { return const_reverse_iterator( begin() ); }
const_reverse_iterator  crbegin() const { return const_reverse_iterator( end() ); }
const_reverse_iterator  crend() const { return const_reverse_iterator( begin() ); }

iterator    begin() { return data; }
iterator    end() { return data + SIZE_; }
const_iterator  begin() const { return data; }
const_iterator  end() const { return data + SIZE_; }
const_iterator  cbegin() const { return data; }
const_iterator  cend() const { return data + SIZE_; }

};

在这个模板中,我们的教授定义了一堆 typedef,其中一些有非常量和常量版本。首先,我想知道每个公共成员的目的是什么,其次,我想知道常量版本在定义数据结构模板的上下文中的目的是什么。

我还注意到一些成员函数被定义为“const”,我想知道这样做的目的是什么。

【问题讨论】:

    标签: c++ arrays templates constants


    【解决方案1】:

    我想知道每个公共成员的目的是什么。

    该类包含以下内容:

    • 类型别名:从类中公开以供公众使用的类型信息。

      • 非常量typedefs 是非const T 的类型别名。
      • const 类型定义是 const T 的类型别名。

      这些typedefs 很有用,因为该类的用户可能需要有关该类型的更多信息。通过使用类暴露的typedef,他可以获得这个。这是一个很好的例子——考虑我们有一个模板类型并且我们需要访问底层迭代器类型的情况。通过使用暴露的类型别名,我们可以访问它:

      template<class Container>
      void example(Container& c)
      {
          typename Container::iterator begin = c.begin(),
          //       ^^^^^^^^^^^^^^^^^^^
                                       end   = c.end();
      }
      

      我想知道常量版本的目的是什么。

      有时用户需要使用const 类型。因此,使用类提供的类型信息使这变得简单。

    我还注意到一些成员函数被定义为“const”,我想知道这样做的目的是什么。

    const 成员函数是不修改任何类数据成员的函数。

    【讨论】:

    • 谢谢。在这个例子中,我想知道为什么需要一个常量迭代器?为什么我们有两个 begin 函数返回一个 const 和 non-const 迭代器?
    • @CanadianCoder 我们永远不知道用户的意图。因此,我们为他们提供了两种选择。例如,如果用户想要使用 const carray 对象,那么他们需要 const 迭代器才能对其进行迭代。他们不能使用非const 版本来做到这一点。
    【解决方案2】:
    1. 所有的 typedef 旨在促进这些类型的使用, std::size_t std::ptrdiff_t 只是无符号整数类型定义。 chech here 用于 reverse_iterator

    2. 为const版本函数的返回值定义的const变量,是为const obj提供的,查看here

    3. 定义为const的成员函数确保函数体中成员变量没有改变,检查here

    【讨论】:

      【解决方案3】:
      1. 为此,我认为你应该尝试使用这个模板,你可能真的知道它为什么需要这样的公共成员。

      2. 当我们使用这个模板对一些数据结构进行操作时,如果我们想修改一些数据,我们需要一个非常量版本。另一方面,如果我们想改变数据的价值,我们需要一个可以帮助我们保护数据的常量版本。

      3. 当您尝试对某些数据进行操作并且您不想修改成员数据时,常量函数可以为您提供帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-19
        • 2013-10-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多