Есть много разных схем, которые люди использовали на протяжении многих лет, некоторые лучше или хуже. Хорошие стратегии определяют жесткую и последовательную модель, которая устанавливает правила «владения» ресурсом, то есть ответственность за очистку и обеспечение того, чтобы ничто не осуществляло незаконный доступ к ресурсу. Правила успешных стратегий также таковы, что для безопасного доступа к ресурсу необходимо только локальное представление о ресурсе и способ его использования.
Стратегия, которую вы должны использовать в современном C ++, называется RAII или «получение ресурсов - инициализация». Это имя означает, что любой приобретенный ресурс должен быть инициализацией. Например:
std::string s = "Hello, World";
Этот код получает некоторую память в качестве ресурса для хранения строковых данных, но все, что вы видите, это то, что строка инициализирована. Инициализированный объект владеет памятью. Это означает, что он отвечает за управление временем жизни памяти и ограничение доступа к ней. Код, использующий объект, вообще не должен учитывать ресурс. Нужно только быть уверенным, что он правильно использует сам объект, и время жизни скрытого ресурса будет корректно управляться по очереди.
Использование RAII не только удобно для обеспечения нормального управления локализованным ресурсом, но также значительно упрощает правильную очистку ресурсов при наличии исключений. При выходе из области действия из-за исключения C ++ гарантирует уничтожение всех полностью созданных объектов в этой области. Если необходимые задачи для очистки ресурсов выполняются деструкторами объектов, то ресурсы не будут вытекать, и нет необходимости добавлять явную обработку исключений для каждой области, в которой используется ресурс.
C ++ уже включает классы, владеющие ресурсами для многих типов ресурсов. Для массива динамического размера используйте std::vector
:
std::vector<CString> xyz()
{
// C++11
return {"hello",...};
// or C++03
std::vector<CString> mappings;
mappings.push_back("hello");
...
return mappings
}
void main(int argc, char **argv)
{
std::vector<CString> tmp = xyz();
// now we have the CString array defined in xyz
// the array gets automatically cleaned up by std::vector's destructor
}