const向量意味着const元素?

时间:2014-11-21 16:09:19

标签: c++ const

const vector<A>是否意味着其元素也是const

在下面的代码中,

v[0].set (1234);中的

void g ( const vector<A> & v ) 产生编译器错误

  

const.cpp:28:3:错误:成员函数'set'不可行:'this'   争论有         输入'const value_type'(又名'const A'),但函数未标记为const

为什么?

(*v[0]).set(1234); void h ( const vector<A *> & v ) 编译器没问题。

版本之间有什么区别?

// ...........................................................
class A {
private:
  int a;
public:
  A (int a_) : a (a_) { }
  int get () const { return a; }
  void set (int a_) { a = a_; }
};

// ...........................................................
void g ( const vector<A> & v ) {
  cout << v[0].get();
  v[0].set (1234); 
} // ()

// ...........................................................
void h ( const vector<A *> & v ) {
  cout << (*v[0]).get();
  (*v[0]).set(1234);
} // ()

4 个答案:

答案 0 :(得分:19)

是的,const vector可以像访问const一样提供对其元素的访问权限,也就是说,它只提供const个引用。在第二个函数中,A类型的对象不是const,而是指针。指针为const并不意味着指针指向的对象是const。要声明指向const的指针,请使用类型A const *

答案 1 :(得分:13)

第一个版本

v[0].set (1234); 

无法编译,因为它尝试更改向量通过引用返回给它的第一个元素。编译器认为这是一个更改,因为set(int)未标记为const

另一方面,第二个版本只有从向量中读取

(*v[0]).set(1234);

并调用set取消引用它返回的指针的常量引用结果。

当您在v[0]向量上致电const时,您会收到constA的引用。当元素类型是指针时,在其上调用set就可以了。您可以将第二个示例更改为

v[0]->set(1234);

并获得与以前相同的结果。这是因为你获得了一个常量指针的引用,但该指针指向的项不是常量。

答案 2 :(得分:9)

因此const对象只能调用const方法。那就是:

class V {
  public:
    void foo() { ... }        // Can't be called
    void bar() const  { ... } // Can be called
};

让我们看一下vector's operator[]

reference       operator[]( size_type pos );
const_reference operator[]( size_type pos ) const;

因此,当vector对象为const时,它将返回const_reference

关于:(*v[0]).set(1234);

让我们打破这个:

A * const & ptr = v[0];
A & val = *ptr;
val.set(1234);

请注意,您有一个指向变量数据的常量指针。因此,您无法更改指向的内容,但您可以更改指针指向的值。

答案 3 :(得分:0)

是的,因为std::vectorvalue-type而不是引用类型。

为简化起见:std::vector将其缓冲区中的值视为自身的一部分,因此更改它们意味着更改矢量。如果仅将向量视为持有指向已分配缓冲区的指针和大小的指针,则可能会造成混淆:在更改缓冲区中的元素时,我们不会更改这两个字段。

与引用类型的指针相反。如果您更改了指向指针的值,则您本身并没有更改指针。

std::vector是一种值类型这一事实是设计选择-这不是C ++语言固有的东西。因此,例如,std::span类基本上也是一对指针和一个大小,但是std::span可以是const,而您仍然可以更改指向的元素。 (跨度和向量之间有other differences。)

相关问题