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);
} // ()
答案 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
时,您会收到const
对A
的引用。当元素类型是指针时,在其上调用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::vector
是value-type而不是引用类型。
为简化起见:std::vector
将其缓冲区中的值视为自身的一部分,因此更改它们意味着更改矢量。如果仅将向量视为持有指向已分配缓冲区的指针和大小的指针,则可能会造成混淆:在更改缓冲区中的元素时,我们不会更改这两个字段。
与引用类型的指针相反。如果您更改了指向指针的值,则您本身并没有更改指针。
std::vector
是一种值类型这一事实是设计选择-这不是C ++语言固有的东西。因此,例如,std::span
类基本上也是一对指针和一个大小,但是std::span
可以是const
,而您仍然可以更改指向的元素。 (跨度和向量之间有other differences。)