Подтвердить что ты не робот

После того, как вы усовершенствовали интеллектуальные указатели, существует ли случай, когда вы используете raw-указатели?

Мне любопытно, как я начинаю принимать больше идиом повышения и, как представляется, лучшие практики. Интересно, в какой момент мой С++ даже отдаленно похож на С++ прошлых лет, часто встречающийся в типичных примерах и в умах из тех, кто не был знаком с "Modern С++"?

4b9b3361

Ответ 1

Немного от головы:

  • Навигация по файлам с отображением памяти.
  • Вызов Windows API, где вам нужно перераспределить (например, LPBITMAPINFOHEADER).
  • Любой код, в котором вы производите произвольную память (VirtualQuery() и т.п.).
  • Почти каждый раз, когда вы используете reinterpret_cast < > на указателе.
  • Каждый раз, когда вы используете новое размещение.

Общий поток здесь - "любая ситуация, в которой вам нужно обрабатывать часть памяти как нечто иное, чем ресурс, над которым у вас есть управление распределением".

Ответ 2

Я почти не использую shared_ptr, потому что я вообще избегаю совместного использования. Поэтому я использую что-то вроде boost::scoped_ptr для "собственного" объекта, но все другие ссылки на него будут грубыми указателями. Пример:

boost::scoped_ptr<SomeType> my_object(new SomeType);
some_function(my_object.get());

Но some_function будет иметь дело с необработанным указателем:

void some_function(SomeType* some_obj)
{
  assert (some_obj);
  some_obj->whatever();
}

Ответ 3

В наши дни я почти полностью отказался от использования указателей на raw. Я даже начал просматривать нашу базу кода для мест, где использовались исходные указатели, и переключил их на вариант интеллектуального указателя. Удивительно, сколько кода я смог удалить, выполнив этот простой акт. Слишком много кода потрачено на управление жизненным циклом необработанных указателей на С++.

Единственные места, где я не использую указатели, - это несколько сценариев взаимодействия с другими базами кода, в которых я не контролирую.

Ответ 4

Я нахожу основное различие между "современным" С++ и старым * материалом - это осторожное использование инвариантов класса и инкапсуляции. Хорошо организованный код, естественно, имеет тенденцию иметь меньше указателей, летающих вокруг. Я почти как нервное плавание в shared_ptrs, так как буду в новостях и удаляю.

Я с нетерпением жду unique_ptr в С++ 0x. Я думаю, что это уберет несколько (умных) указателей, которые все еще бродят по дикой природе.

* все еще, к сожалению, очень распространенный

Ответ 5

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

На самом деле всегда безопасно передавать необработанный указатель на функцию, если функция не пытается сохранить копию указателя в глобальной или членной переменной или попытаться удалить ее. С этими ограничениями функция не может повлиять на время жизни объекта, и единственной причиной умного указателя является управление временем жизни объекта.

Ответ 6

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

Управляемая память почти всегда превосходит необработанную, потому что это означает, что вам не нужно иметь дело с удалением ее в нужном месте, но все же иметь большой контроль над точками построения и уничтожения ваших указателей.

О, и там еще одно место для использования необработанных указателей:

boost::shared_ptr<int> ptr(new int);

Ответ 7

Я все еще использую raw-указатели на устройствах с памятью IO, например встроенными системами, где наличие интеллектуального указателя на самом деле не имеет смысла, потому что вам никогда не понадобится или не сможет delete его.

Ответ 8

Если у вас есть круговые структуры данных, например, A указывает на B и B, указывает на A, вы не можете наивно использовать интеллектуальные указатели для A и B, так как тогда объекты будут освобождены только от дополнительной работы. Чтобы освободить память, вам необходимо вручную очистить интеллектуальные указатели, что примерно так же плохо, как удалить умные указатели.

Возможно, это случается очень редко, но предположим, что у вас есть объект родителя, который имеет интеллектуальные указатели на кучу дочерних объектов. Где-то по пути кому-то нужно найти родителя для ребенка, поэтому они добавляют к ребенку умный указательный элемент, который указывает на родителя. Без памяти память больше не освобождается.

Требуется некоторая осторожность. Умные указатели не эквивалентны сборке мусора.

Ответ 9

Я пишу С++, который должен сосуществовать с Objective C (используя Objective С++ для моста). Поскольку объекты С++, объявленные как часть классов Objective С++, не имеют конструкторов или деструкторов, вы не можете их действительно удерживать в интеллектуальных указателях.

Поэтому я стараюсь использовать raw-указатели, хотя часто с boost:: intrustive_ptr и внутренним количеством ссылок.

Ответ 10

Не то, чтобы я это сделал, но вам нужны исходные указатели для реализации, скажем, связанного списка или графика. Но было бы гораздо умнее использовать std::list<> или boost::graph<>.