Почему auto_ptr может "запечатать" контейнер - PullRequest
1 голос
/ 15 июня 2010

auto_ptr в википедии говорит, что «auto_ptr, содержащий контейнер STL, может использоваться для предотвращения дальнейшей модификации контейнера».Он использовал следующий пример:

auto_ptr<vector<ContainedType> > open_vec(new vector<ContainedType>);

open_vec->push_back(5);
open_vec->push_back(3);

// Transfers control, but now the vector cannot be changed:
auto_ptr<const vector<ContainedType> > closed_vec(open_vec); 

// closed_vec->push_back(8); // Can no longer modify

Если я раскомментирую последнюю строку, g ++ сообщит об ошибке как

t05.cpp:24: error: passing ‘const std::vector<int, std::allocator<int> >’ 
as ‘this’   argument of ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) 
[with _Tp = int, _Alloc = std::allocator<int>]’ discards qualifiers

Мне интересно, почему после передачи права собственности на этот векторбольше не может быть изменено?

Большое спасибо!

Ответы [ 2 ]

4 голосов
/ 15 июня 2010

Указатель closed_vec содержит тип const vector<ContainedType>.Поскольку типом является const, вы не можете вызывать для него методы, которые также не определены как const (что означает, что они не изменяют внутренние данные).Естественно, push_back не является константным, так как он меняет вектор, поэтому вы не можете вызвать его по константному указателю.Это на самом деле не имеет ничего общего с auto_ptr, вы можете сделать то же самое с обычными указателями:

vector<ContainedType>* open_vec = new vector<ContainedType>();
open_vec->push_back(5);
open_vec->push_back(3);

const vector<ContainedType>* closed_vec = open_vec;
closed_vec->push_back(8); // Fails
1 голос
/ 16 июня 2010

Вы не можете изменить вектор, потому что closed_vec является указателем на константу, поэтому компилятор не позволит вам изменить указатель (но вы все равно можете переместить указатель). Чтобы разрешить изменение вектора, объявите closed_vec как

auto_ptr<vector<ContainedType> > closed_vec(open_vec); // no const anymore
closed_vec->push_back(8); // this now works

Если вы объявили указатель как

const auto_ptr<vector<ContainedType> > closed_vec(open_vec);

с другой стороны, вы сможете изменить указатель, но не перемещать указатель.

...