Boost::any::operator= (Зачем swap?)

Модератор: Модераторы разделов

Аватара пользователя
Zeus
Сообщения: 694

Boost::any::operator=

Сообщение Zeus »

Полез тут в boost/any.hpp поглядеть на операторы присваивания.
Сначала испужался было, что он меняет значения операндов, хотя вроде ж ему константную ссылку передют.
Потом пригляделся: там создаётся временный объект boost::any с новым значением, а потом делается swap.
Зачем? Почему просто не скопировать значение права налево?

Вопрос досужий - пока ни на что не влияет :)
Спасибо сказали:
Аватара пользователя
Skladnoy
Сообщения: 90
ОС: Debian

Re: Boost::any::operator=

Сообщение Skladnoy »

Если я все правильно понимаю,

Код: Выделить всё

template<typename ValueType> any & operator=(const ValueType & rhs)
{
    any(rhs).swap(*this);
    return *this;
}

то дело состоит в том что сначала создается временный объект, в него помещается текущее содержание объекта. Он удаляется а вместе в ним удаляется старое содержание.
Значение копируемого объекта оказывает в нашем объекте. Старое удалено. Финита
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Boost::any::operator=

Сообщение v04bvs »

Подробно объяснять долго, погугли по exception safe assignment operator. Основная мысль - если вылетает исключение где нибудь, то объект остаётся в неизменном состоянии. Т.е. если вылетает исключение, то оно гарантированно вылетает в конструкторе копирования, и летит дальше, у исходного объекта состояние не изменилось. Если не вылетело, то опять же всё в порядке, т.к. swap гарантированно не кидает исключение.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: Boost::any::operator=

Сообщение Zeus »

Хм... swap исключение не выбрасывает, а операция присваивания - выбросит? : /
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Boost::any::operator=

Сообщение v04bvs »

Zeus писал(а):
08.05.2007 09:57
Хм... swap исключение не выбрасывает, а операция присваивания - выбросит? : /

Да. Это обычно можно легко сделать. Пример: класс строка

Код: Выделить всё

string::string(const string& rhs)
{
  m_data = new char[rhs.m_length + 1]; // exception could be thrown
  m_length = rhs.m_length;
  strncpy(m_data, rhs.m_data, m_length);
}

void string::swap(string& rhs) throw ()
{
  std::swap(m_data, rhs.m_data); // no exceptions could be thrown
}
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: Boost::any::operator=

Сообщение Zeus »

Ухум.
Типа при swap'е не происходит работа с памятью...
Понятно.
Спасибо сказали:
Аватара пользователя
agbr
Сообщения: 486
ОС: openSUSE 10.2

Re: Boost::any::operator=

Сообщение agbr »

это все для того, чтобы если произойдет исключение состояние объектов осталось таким, каким было до начала операции.
jabber: agbr@jabber.ru

против проприетарного ПО в GNU/Linux
Спасибо сказали: