一个非元素向量,其元素不能改变 - 替代

时间:2012-12-08 13:12:25

标签: c++

我很痴迷于制作真正应该const的{​​{1}},即使这样做有点痛苦。

在这种情况下,我想要一个const我可以添加元素,但我现有的元素我无法改变。问题是vector<int>是不允许的。

目的不仅是为了防止我的类的用户修改他们不应该修改的东西(这可以通过成员函数中的vector<const int>迭代器轻松完成)。同样重要的是,我自己以后不会在我自己的代码中做我不打算做的事情

我找到了两个选择:

  • 请改用const

  • 创建我自己的包含实际deque<const int>的矢量类,就像这样(我在这里为vector执行此操作,但实际上我会使用模板来实现通用性)

    int

您会推荐以下哪些想法(或其他)?编译器是否会将第二种替代方法转换为与直接使用向量一样快的代码?

3 个答案:

答案 0 :(得分:1)

你的痴迷是可以理解的,我并不反对,但除非你有一个非常紧迫的需要,否则所需的努力可能不值得。

假设您根据设计要求选择vector作为容器,我建议不要将其更改为deque或任何其他类型。它只会让未来的读者感到困惑(可能是你自己),否则也是一种不好的做法。

如果我们使用你的包装器解决方案,你必须 hide 覆盖可以修改向量的所有成员,这是一个问题,因为有很多方法用于访问和修改,例如operator[]at()front()back()。这可能会使未来的读者感到困惑,因为他们习惯于“标准”vector行为。

顺便问一下,你确定deque<const int> foo;有效吗?我收到以下错误:

error: invalid conversion from 'const void*' to 'void*'

编辑似乎我没有完全回答你的问题。如果您选择一个,我会选择包装方法。

答案 1 :(得分:1)

我更喜欢私有继承这类标准容器 - 几乎完全适合我的需求案例。公共继承通过指向基类的指针导致切片或非虚拟破坏。构图需要额外的打字。

私人继承和using的使用很好地表达了您的意图。

这是一个例子:

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

class my_vector : private std::vector<int> {
  // Utility type 
  typedef std::vector<int> base;
public:
  // Types I don't need to tweak:
  using base::value_type;
  using base::allocator_type;
  using base::size_type;
  using base::difference_type;
  using base::const_reference;
  using base::const_pointer;
  using base::const_iterator;
  using base::const_reverse_iterator;

  // Types I do need to tweak:
  typedef const_reference reference;
  typedef const_pointer pointer;
  typedef const_iterator iterator;
  typedef const_reverse_iterator reverse_iterator;

  // Constructors
    // Implicit constructors OK
  // Destructors
    // Implicit destructors OK
  // Assignment
    // Implicit assignment OK

  // Methods that I don't need to tweak:
  using base::assign;
  using base::get_allocator;
  using base::empty;
  using base::size;
  using base::max_size;
  using base::reserve;
  using base::capacity;
  using base::clear;
  using base::push_back;
  using base::pop_back;
  using base::swap;

  // Methods I need to tweak
  const_reference at( size_type pos ) const { return base::at(pos); }
  const_reference operator[](size_type pos) const { return base::operator[](pos); }
  const_reference front() const { return base::front(); }
  const_reference back() const { return base::back(); }
  const_iterator begin() const { return base::begin(); }
  const_iterator end() const { return base::end(); }
  const_reverse_iterator rbegin() const { return base::rbegin(); }
  const_reverse_iterator rend() const { return base::rend(); }

  // Methods I need to delete:
    // base::insert;
    // base::erase;
    // base::resize;

};

int main () {
  my_vector m;
  m.push_back(1);
  m.push_back(2);
  m.push_back(3);
  my_vector m2;
  m2 = m;
  std::copy(m2.begin(), m2.end(), std::ostream_iterator<int>(std::cout, "\n"));
}

答案 2 :(得分:0)

标准容器没有什么神奇之处。如果您需要一个具有与标准容器不同的特性的容器,请编写自己的容器。如果其中一个标准容器接近您所需的容器,请将其用作内部实现。简而言之,my_vector是可行的方法。