Действительно ли общее владение объектов является знаком плохого дизайна?

Фон: читая газеты и часто задаваемые вопросы доктора Stroustrup, я замечаю некоторые сильные "мнения" и большие советы от легендарного ученого CS и программиста. Один из них о shared_ptr в C++ 0x. Он начинает объяснять о shared_ptr и как это представляет совместно использованное владение резкого объекта. В последней строке он говорит, и я заключаю в кавычки:

. A shared_ptr представляет совместно использованное владение, но совместно использованное владение не является моим идеалом: лучше, если объект имеет определенного владельца и определенную, предсказуемую продолжительность жизни.

Мой Вопрос: До какой степени RAII заменяет другими шаблонами разработки как Сборка "мусора"? Я предполагаю, что ручное управление памятью не используется для представления совместно использованного владения в системе.

11
задан AraK 25 December 2009 в 03:11
поделиться

3 ответа

В какой степени RAII заменяет другие шаблоны дизайна, такие как "Сборка мусора"? Я предполагаю, что ручное управление памятью не используется для представления общей собственности в системе

Хмм, в случае с GC, вам на самом деле не нужно думать о собственности. Объект остается в системе до тех пор, пока он нужен любому. Совместное владение - это стандартный и единственный выбор.

И конечно, все можно сделать с помощью совместного владения. Но иногда это приводит к очень неуклюжему коду, потому что вы не можете контролировать или ограничивать время жизни объекта. Вы должны использовать C#, используя блоки, или попробовать /finally с вызовами close/dispose в пункте finally, чтобы гарантировать, что объект будет очищен, когда он выйдет из области видимости.

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

RAII в значительной степени заменяет GC. В 99% случаев совместное владение - это не то, что вы хотите в идеале. Это приемлемый компромисс, в обмен на то, чтобы сэкономить много головной боли, получив сборщик мусора, но на самом деле он не соответствует тому, что вы хотите . Вы хотите , чтобы ресурс в какой-то момент умер. Ни до, ни после. Когда RAII является опцией, это приводит к более элегантному, лаконичному и робастному коду в этих случаях.

RAII, однако, не идеален. В основном потому, что он не так хорошо справляется с случайным случаем, когда вы просто не знаете время жизни объекта. Он должен остаться надолго, до тех пор, пока кто-то им пользуется. Но вы не хотите хранить его вечно (или до тех пор, пока область видимости, окружающая всех клиентов, которая может быть всего лишь основной функцией).

В таких случаях пользователям С++ приходится "понижать" семантику владения, обычно реализуемую подсчётом по ссылке через shared_ptr. И в этом случае ГК выигрывает. Он может реализовывать совместную собственность гораздо более надежно (способен обрабатывать циклы, например), и более эффективно (Амортизированная стоимость подсчета ссылок составляет огромную по сравнению с приличным ГК)

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

.
14
ответ дан 3 December 2019 в 03:04
поделиться

Задача программиста - элегантно выражать вещи на выбранном им языке.

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

Если нет хорошего способа поместить объект прямо в стек, то, возможно, его можно поместить в другой объект в качестве члена. Теперь его время жизни немного больше, но C++ все равно делает многое автоматически. Время жизни объекта ограничено родительским объектом - проблема была делегирована.

Однако, одного родителя может и не быть. Следующее лучшее - это последовательность усыновителей. Для этого и существует auto_ptr. Все равно неплохо, потому что программист должен знать, какой именно родитель является владельцем. Время жизни объекта ограничено временем жизни его последовательности владельцев. Одним из шагов по цепочке в детерминизме и элегантности является shared_ptr: время жизни объекта делится на время жизни его последовательности владельцев.

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

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


Извините за разглагольствования, но я думаю, что лучший способ ответить на ваш вопрос - контекст: shared_ptr - это просто инструмент для вычисления времени жизни объекта, который вписывается в широкий спектр альтернатив. Он работает, когда работает. Его следует использовать, когда он элегантен. Его не следует использовать, если у вас меньше пула владельцев, или если вы пытаетесь вычислить какую-то сложную функцию, используя ее как извилистый способ инкремента/декремента.

.
8
ответ дан 3 December 2019 в 03:04
поделиться

Является ли сборка мусора дизайнерской моделью? Я не знаю.

Большим преимуществом совместного владения является присущая ему предсказуемость. С ГК возврат ресурсов не в твоих руках. В том-то и дело. Когда, и как это происходит, обычно не в голову разработчика, использующего его. С общим владением, вы контролируете ситуацию (остерегайтесь, иногда слишком большой контроль - это плохо). Допустим, ваше приложение порождает миллион share_ptr'ов для X. Все это ваше дело, вы отвечаете за них, и у вас есть полный контроль над тем, когда эти ссылки создаются и уничтожаются. Поэтому решительный и внимательный программист должен точно знать, кто на что ссылается и как долго. Если вы хотите, чтобы объект был уничтожен, вы должны уничтожить все общие ссылки на него, и viola, он исчез.

Это влечёт за собой некоторые глубокие последствия для людей, которые делают программное обеспечение в реальном времени, которое ДОЛЖНО быть полностью предсказуемым. Это также означает, что вы можете подтасовать так, что это будет выглядеть ужасно похоже на утечку памяти. Лично я не хочу быть решительным и внимательным программистом, когда мне не нужно им быть (иди и смейся, я хочу ездить на пикники и велосипедные прогулки, не считая моих ссылок), так что там, где это уместно, GC - мой предпочтительный маршрут. Я написал немного звукового программного обеспечения в реальном времени, и использовал общие ссылки для предсказуемого управления ресурсами.

Ваш вопрос: Когда RAII терпит неудачу? (В контексте общих ссылок) Мой ответ: Когда вы не можете ответить на вопрос: у кого может быть ссылка на это? Когда развиваются порочные и глупые круги собственности.

Мой вопрос: Когда ГК терпит неудачу? Мой ответ: Когда вы хотите полного контроля и предсказуемости. Когда GC написана Sun Microsystems в последнюю минуту и имеет нелепое поведение, которое могло быть спроектировано и реализовано только сильно пьяными прото-человеческими кодовыми обезьянами, позаимствованными у Microsoft.

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

.
3
ответ дан 3 December 2019 в 03:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: