Читал Википедию для RAII когда только что увидел Single
а также Shared
владение.
Погуглил и не смог найти полезного ответа!
Может ли кто-нибудь объяснить эту концепцию школьнику?
Это по сути unique_ptr
против shared_ptr
,
Единоличное владение, иначе называемое уникальным владением, означает, что ресурс принадлежит не замужем экземпляр класса. Как только этот экземпляр перестает существовать, ресурс освобождается (через деструктор). Большинство классов RAII, которые вы найдете, имеют уникальную собственность, такую как std::vector
,
Совместное владение означает, что ресурс общий между несколькими экземплярами классов. Ресурс освобождается только после того, как каждый экземпляр перестает существовать и, следовательно, требует какой-либо формы подсчета ссылок или сбора мусора. Примером того, где вы хотели бы иметь общее владение, является дескриптор очень дорогого для копирования неизменяемого ресурса. Я видел, как это используется в графиках тоже.
Это может помочь мыслить с точки зрения указателей. Одиночное владение будет иметь только 1 указатель-владелец, общее — Конечно, RAII может не включать указатели.
+---------------+
|Shared instance|
+--------+ +------------+--+ +---------------+
|Resource| | +----------+Shared instance|
+--------+ v v +---------------+
^ +--------+
| |Resource|<-----------+
| +--------+ +---+-----------+
| ^ |Shared instance|
+------+--------+ | +---------------+
|Unique Instance| |
+---------------+ |
+------+--------+
|Shared instance|
+---------------+
Владение сильно связана с концепцией переменное время жизни.
Если вы можете ответить на вопрос, когда нормально, когда этот кусок памяти уходит?, тогда вы можете ответить на вопрос о собственности.
Если этот кусок памяти связан только с временем жизни одной переменной, то у вас есть один владелец.
Обратите внимание, что также важно думать о куча или же динамический распределение против стек или же автоматический переменные. С автоматические переменные, когда они выходят из области видимости, память, связанная с ними, пожинается. С динамическое распределение, в общем случае это не так. Если вы используете новые объекты, такие как станд :: unique_ptr<> для единоличного владения вы можете очистить часть динамической памяти, когда она выходит из области видимости. Если есть много ссылок на этот кусок памяти с неопределенным порядком, когда ссылки исчезнут, то вам может понадобиться что-то вроде станд :: shared_ptr<> для множественного владения.
Собственность сводится к тому, кто несет ответственность за освобождение ресурса. Обычно вы можете сказать, что одна часть кода (будь то функция или класс) является единственным владельцем ресурса. Когда это будет сделано с ресурсом, владелец должен будет освободить его, чтобы ресурс не утечка. Это известно как одиночный или уникальный владение.
Кроме того, существует концепция общий владение, когда две или более отдельных части кода, опять же, они могут быть классами или функциями, оба рассчитывают на один и тот же ресурс. В этом случае оба ресурса больше не нуждаются в ресурсе, прежде чем он может быть освобожден.
C ++ предоставляет две полезные оболочки для передачи и применения семантика собственности — семантика владения — это то, что описано выше. Эти обертки обобщают концепцию RAII — автоматическое освобождение ресурса после его выхода из области видимости.
unique_ptr
— Объект, заключенный в уникальный указатель, будет немедленно освобожден, когда он выйдет из области видимости, то есть функция вернется или класс будет уничтожен.
shared_ptr
— Объект, обернутый в общий указатель, будет оставаться доступным до тех пор, пока все «сильные ссылки» не выйдут из области видимости. Это понятие, известное как подсчет ссылок. Как только окончательная ссылка выходит из области видимости, ресурс освобождается.
Семантика владения невероятно важна в таких языках, как C ++, поэтому я рекомендую вам ознакомиться с тем, как современный C ++ передает и применяет это. Вы можете начать с изучения правильного использования unique_ptr
а также shared_ptr
,
Что касается интеллектуальных указателей / raii, совместное владение — это когда несколько объектов могут ссылаться на один и тот же ресурс, и этот ресурс освобождается только тогда, когда все экземпляры этого объекта, ссылающиеся на ресурс, деконструированы.
// shared ownership
{
std::shared_ptr<SomeClass> i(new SomeClass());
{
std::shared_ptr<SomeClass> j = i;
{
std::shared_ptr<SomeClass> k = j;
// at this point i, j, k all own the same object
}
// k deconstructed and no longer shares ownership of the resource
}
// j deconstructed and no longer shares ownership of the resource
}
// i deconstructed and he resource is also released / free'd
При совместном (уникальном) владении либо умирает вместе с объектом, либо передается другому объекту
// single/unique ownership
{
std::unique_ptr<SomeClass> i(new SomeClass());
{
std::unique_ptr<SomeClass> j = std::move(i); // k takes ownership of the object from i
}
// j is deconstructed and the resource is also released / free'd
}
// i deconstructed and nothing is released, as the ownership already passed to j
Единоличное владение означает, что когда владелец закончил работу с ресурсом, он должен удалить его.
Если он является общим владельцем, он не может удалить его, потому что другой владелец (ы) все еще может его использовать! Таким образом, удаление ресурса должно координироваться с помощью некоторых средств, обычно путем подсчета ссылок.