Codejacked покрывает три различных метода о том, как сравнить документы слова.
Судя по всему, люди, написавшие этот код, были теми, кто что-то упустил. Единственный раз, когда имело бы смысл вызывать clear () в ctor или dtor, было бы в середине другого кода. Например, оператор может прочитать некоторые данные, обработать их, а затем прочитать дополнительные данные. В таком случае, вероятно, быстрее использовать один контейнер для данных по мере их чтения и очищать каждый раз, чем создавать новый контейнер на каждой итерации.
Нет, вы ничего не упустили. Я подозреваю, что это (безобидное) программирование вуду, что-то вроде установки указателя на null после его освобождения или случайного вызова repaint / revalidate в коде графического интерфейса. Программист вспоминает, что это помогало с какой-то ошибкой в прошлом, и теперь добавляет ее без надобности «на всякий случай». Кто знает, может, это поможет. Вуду.
Учтите следующее:
#define BOOST_TEST_MODULE StlContainers
#define BOOST_LIB_DIAGNOSTIC
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/assign/std/vector.hpp>
#include <vector>
using namespace boost::assign;
using namespace std;
const vector<int> my_ints_vector = list_of(0)(1)(1)(2)(3)(5)(8)(13)(21)(34);
struct ScopedStruct1
{
ScopedStruct1(const vector<int> & v) : m_v(v) {}
~ScopedStruct1() {}
private :
vector<int> m_v;
};
class A
{
public :
A(int i) : m_i(i) {}
~A() {}
private :
int m_i;
};
struct ScopedStruct2
{
ScopedStruct2() {}
~ScopedStruct2() { for(vector<A*>::iterator it = m_v.begin(); it != m_v.end(); ++it) delete *it; }
vector<A*> m_v;
};
struct ScopedStruct3
{
ScopedStruct3() {}
~ScopedStruct3() { /* no deletion */ }
vector<A*> m_v;
};
BOOST_AUTO_TEST_CASE(StlContainer_storing_something_simple)
{
ScopedStruct1 str(my_ints_vector);
}
BOOST_AUTO_TEST_CASE(StlContainer_storing_pointers_with_delete)
{
ScopedStruct2 str;
for(int i = 0; i < 10; i++)
str.m_v.push_back(new A(i));
}
BOOST_AUTO_TEST_CASE(StlContainer_storing_pointers_without_delete)
{
ScopedStruct3 str;
for(int i = 0; i < 10; i++)
str.m_v.push_back(new A(i));
}
Используя структуру boost unit_test, я создал 3 тестовых примера. Фреймворк unit_test хорош, потому что он отслеживает утечки памяти. Вы заметите, что 1-й и 2-й тестовые примеры не вызывают утечек памяти, но 3-й случай вызывает, потому что содержимое вектора не удаляется.
Нет, ты прав. Если в конструкторе (или конструкторе базовых классов) нет каких-то дополнительных дел, которые требуют этого, но шансы очень низкие ...
Позднее редактировать
В случае деструктора, одна из самых распространенных ошибок I Видно, что некоторые люди предполагают, что метод clear также будет вызывать удаление векторов указателей (vector), что, конечно, не так
Единственный случай, который я могу придумать, где это было бы полезно, - это когда порядок уничтожения имеет значение, и деструктор хочет гарантировать, что объекты в векторе будут уничтожены раньше, чем что-то еще.
Конечно, лучше структурировать код так, чтобы этого не требовалось; однако это вполне объяснимая причина.
Конечно, нужно вызвать clear () или resize (0) или эквивалентный say (std :: _ Destroy_range (...) в деструкторе перед освобождением.
Освобождение выполнено через allocator :: deallocate , который НЕ запускает деструкторы . Он просто освобождает память.
clear () эквивалентен resize (0), который запускает деструкторы для объектов first size () в выделенном buffer
НЕ только выделенные указатели, дескрипторы файлов, удерживаемые мьютексы, все другие восстанавливаемые ресурсы, удерживаемые объектом. Деструкторы ДОЛЖНЫ запускаться. Перед созданием экземпляра шаблон не знает, что деструктор тривиален. Если деструктор тривиален, ТОГДА он оптимизируется ПОСЛЕ создания экземпляра
Несмотря на то, что было сказано до сих пор, существует по крайней мере один сценарий, когда может потребоваться явный вызов clear
в деструкторе.
Представьте себе ситуацию, когда у уничтожаемого объекта есть несколько подобъектов-членов, которые требуют определенного порядка уничтожения, т.е. подобъекты каким-то образом зависят друг от друга, и неправильный порядок их разрушения приведет к нежелательным результатам. Как вы, наверное, знаете, порядок уничтожения подобъекта члена (а также инициализации члена) определяется порядком объявления членов в определении класса. Так, один из способов добиться правильного порядка уничтожения - это расположить объявления членов соответствующим образом. Однако, во-первых, это не очень хорошее решение с точки зрения обслуживания. Во-вторых, желаемый порядок уничтожения может зависеть от некоторых условий выполнения. В-третьих, желаемый порядок уничтожения может противоречить желаемому порядку инициализации. Все это означает, что может быть невозможно (или неразумно) указать правильный порядок уничтожения, переупорядочив объявления.
Разумным подходом в этом случае может быть очистка некоторых критических подобъектов-членов вручную, вызывая их методы clean
или подобные, до тех пор, пока зависимость порядка уничтожения не «исчезнет». Я бы предположил,