Я думаю, что здесь был дан немного более подробный ответ: Какой тип указателя мне использовать, когда?
Из этой ссылки извлечено: "Использовать тупые указатели (необработанные указатели) илиссылки на не владеющих ссылками на ресурсы и когда вы знаете, что ресурс переживет ссылающийся объект / область. "(выделено жирным шрифтом из оригинала)
Проблема в том, что если вы пишете код для общего пользования, не всегда легко быть абсолютно уверенным, что объект переживет необработанный указатель.Рассмотрим следующий пример:
struct employee_t {
employee_t(const std::string& first_name, const std::string& last_name) : m_first_name(first_name), m_last_name(last_name) {}
std::string m_first_name;
std::string m_last_name;
};
void replace_current_employees_with(const employee_t* p_new_employee, std::list<employee_t>& employee_list) {
employee_list.clear();
employee_list.push_back(*p_new_employee);
}
void main(int argc, char* argv[]) {
std::list<employee_t> current_employee_list;
current_employee_list.push_back(employee_t("John", "Smith"));
current_employee_list.push_back(employee_t("Julie", "Jones"));
employee_t* p_person_who_convinces_boss_to_rehire_him = &(current_employee_list.front());
replace_current_employees_with(p_person_who_convinces_boss_to_rehire_him, current_employee_list);
}
К своему удивлению, функция replace_current_employees_with()
может непреднамеренно вызвать освобождение одного из ее параметров до того, как она его закончит.
Так что, даже если она можетна первый взгляд кажется, что функция replace_current_employees_with()
не нуждается в владении своими параметрами, ей нужна какая-то защита от возможности коварного освобождения ее параметров до того, как они закончат их использовать.Самое простое решение - фактически взять (временно совместно) владеть параметром (ами), предположительно через shared_ptr
.
Но если вы действительно не хотите вступать во владение, теперь есть безопасный вариант- и это бесстыдная часть ответа - « зарегистрированных указателей ».«зарегистрированные указатели» - это интеллектуальные указатели, которые ведут себя как необработанные указатели, за исключением того, что они (автоматически) устанавливаются на null_ptr
, когда целевой объект уничтожается, и по умолчанию выдают исключение, если вы пытаетесь получить доступ к объекту, который ужебыл удален.
Также обратите внимание, что зарегистрированные указатели могут быть «отключены» (автоматически заменены их необработанными аналогами указателей) с помощью директивы времени компиляции, что позволяет использовать их (и нести накладные расходы) в debug / test /только бета-режимы.Так что вам действительно придется прибегать к реальным необработанным указателям довольно редко.