Требуется разъяснение по boost:: необязательный тип

#c #boost-optional

#c #boost-необязательно

Вопрос:

Я пытаюсь разобраться в нескольких деталях, полученных из основного файла, в отношении boost:: необязательная переменная типа.

Переменная:

 boost::optional<Cacher> cacher_;
  

Кадр # 5 из ядра:

 (gdb) p this->cacher_
$1 = boost::optional
  

Строка, выполняемая в этом фрейме, является:

 cacher_ = boost::none;
  

В результате несколько кадров, приведших к сбою, указывают на код библиотеки boost:

 #1  0x000000000152f96c in destroy_impl (this=0x32557590) at /opt/include/boost/optional/optional.hpp:479
#2  destroy (this=0x32557590) at /opt/include/boost/optional/optional.hpp:439
#3  assign (this=0x32557590) at /opt/include/boost/optional/optional.hpp:313
#4  operator= (none_=NULL, this=0x32557590) at /opt/include/boost/optional/optional.hpp:615
  

Фрейм # 0 — это место, где Cacher вызывается деструктор, а сбой происходит из-за того, что память, удерживаемая объектом, уже освобождена.

Мой вопрос:

  1. boost::optional Указывает ли, что память, удерживаемая, cacher_ действительна?
  2. В результате присвоения boost::none cacher_ будет ли объект уничтожен?

Приносим извинения, если деталей для диагностики проблемы недостаточно. Я постараюсь предоставить дополнительную информацию на основе ответов.

Спасибо!

Ответ №1:

Да, boost::optional отслеживает, содержит ли он допустимый объект. Это можно проверить с помощью operator bool() или is_initialized() .

Если вы назначите boost::none (или вызовете .reset() ), он должным образом уничтожит объект, который он содержит, если таковой имеется.

То же самое справедливо и для std::optional (за исключением boost::none присваивания, насколько мне известно).

Комментарии:

1. (gdb) frame 3 #3 assign (this=0x32557590) at /opt/ include/boost/optional/optional.hpp:313 313 void assign ( none_t ) { destroy(); } (gdb) p *this $9 = {<boost::optional_detail::optional_tag> = {<No data fields>}, m_initialized = false, m_storage = {dummy_ = { data = “………………………………….", aligner_ = {<No data fields>}}}} m_initialized = false Указывает ли, что объект недействителен?

2. Я не думаю, что valid — это правильный термин. Необязательный тип пуст, в нем нет объекта. Вроде как пустой unique_ptr (необязательный очень похож на интеллектуальный указатель, но мы используем его для ясности).

3. ОК. В данном случае, что мы пытаемся уничтожить, когда объекта нет? В любом случае, правильно ли назначать boost::none без проверки того cacher_ , инициализирован он или нет?

4. Если объекта нет, ничто не должно быть уничтожено. Безопасно назначать boost::none такому необязательному, но он должен оставить его в идентичном состоянии (например, присвоение nullptr уже пустому unique_ptr )

5. Разве деструктор не вызывается для объекта? Чего мне не хватает в данном случае?