Подтвердить что ты не робот

Const вектор подразумевает const-элементы?

Значит ли const vector<A>, что его элементы также const?

В приведенном ниже коде

v[0].set (1234); в void g ( const vector<A> & v ) создает ошибку компилятора

const.cpp: 28: 3: ошибка: функция-член 'set' не жизнеспособна: 'this'аргумент       type 'const value_type' (aka '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);
} // ()
4b9b3361

Ответ 1

Первая версия

v[0].set (1234); 

не компилируется, потому что он пытается изменить первый элемент вектора, возвращенный ему ссылкой. Компилятор считает это изменением, потому что set(int) не помечен const.

Вторая версия, с другой стороны, только читает из вектора

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

и вызывает set в результате разыменования константы ссылки на указатель, который он возвращает.

Когда вы вызываете v[0] в векторе const, вы возвращаете ссылку const на A. Когда тип элемента является указателем, вызов set на нем в порядке. Вы можете изменить второй пример на

v[0]->set(1234);

и получите тот же результат, что и раньше. Это связано с тем, что вы получаете ссылку на указатель, который является константой, но элемент, на который указывает этот указатель, не является константой.

Ответ 2

Да, const vector предоставляет доступ к элементу, как если бы они были const (то есть давали ссылки const). В вашей второй функции не объекты типа A являются const, а указывают на них. Указатель const не означает, что объект, на который указывает указатель, равен const. Чтобы объявить указатель на константу, используйте тип A const *.

Ответ 3

Таким образом, объект const может вызывать только вызовы методов const. То есть:

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

Итак, посмотрим на оператор vector []:

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

Итак, когда векторный объект const, он вернет a const_reference.

О программе: (*v[0]).set(1234);

Давайте сломаем это:

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

Обратите внимание, что у вас есть постоянный указатель на переменные данные. Таким образом, вы не можете изменить то, на что указали, но вы можете изменить значение, на которое указывает указатель.