scoped_ptr право собственности

Возможный дубликат:
Что такое умный указатель и когда его использовать?

Я читал статью и нашел небольшой пример, демонстрирующий использование boost::scoped_ptr<T>:

#include <cstdlib>
#include <iostream>
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>

static int count = 0;

class printer
{
    int m_id;

public:
    printer(void) :
        m_id(count++)
    {
    }

    ~printer(void)
    {
        std::cout << "Printer " << m_id
                  << " destroyed" << std::endl;
    }
};

int
main(void)
{
    boost::scoped_ptr<printer> p1(new printer);
    boost::scoped_ptr<printer> p2(new printer);
    std::cout << "Exiting test program" << std::endl;

    return EXIT_SUCCESS;
}

Единственное, чего я не понял в статье, так это такого утверждения:

используя scoped_ptr, вы указываете, что передача права собственности не предусмотрена и не разрешена.

Возможно, это была неправильная статья для новичка в этой теме, но что именно означает приведенная выше строка?


person SandBag_1996    schedule 02.02.2013    source источник
comment
Да, это была не та статья. Ответом на этот вопрос является целая книга по C ++, но SO не позволяет мне публиковать ответ так долго.   -  person Lightness Races in Orbit    schedule 02.02.2013
comment
вся книга C ++? Хорошо! Хотя, искренне сомневаюсь .. Можете ли вы сделать небольшую попытку дать небольшой обзор. Я изо всех сил постараюсь понять   -  person SandBag_1996    schedule 02.02.2013
comment
Вы пробовали публиковать по два ответа на половину меньше времени?   -  person thang    schedule 02.02.2013
comment
@thang: Да :( Я дошел до постов размером 1/16, но потом сдался.   -  person Lightness Races in Orbit    schedule 02.02.2013
comment
@LightnessRacesinOrbit Итак, теоретически вы можете делать 16 постов на 1/16 длины.   -  person thang    schedule 02.02.2013
comment
Я хочу отметить как дубликат stackoverflow.com/questions/106508/, но система была нарушена из-за преждевременного развертывания функции.   -  person Lightness Races in Orbit    schedule 02.02.2013
comment
Я предполагаю, что это просто то, что область объявления интеллектуального указателя не может быть изменена, поскольку scoped_ptr является классом стека. Передача этого в другую область приведет к появлению двух идентичных указателей на одну и ту же область памяти (из-за конструктора копирования, который должен присутствовать для поддержки этого), и, таким образом, выход из одной области приведет к разрушению объекта и вызовет другой указатель стать инвалидом. Конечно, это бессвязное предположение, поэтому я могу ошибаться.   -  person slugonamission    schedule 02.02.2013


Ответы (1)


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

boost::scoped_ptr имеет очень строгую семантику владения. Он вообще не допускает передачи права собственности. Это достигается тем, что его нельзя копировать (поэтому вы не можете передать его другой функции по значению).

Другой пример: std::unique_ptr тоже довольно строгий. Его особая способность заключается в том, что его можно перемещать. Передача std::unique_ptr функции в качестве rvalue позволит этой функции украсть право собственности на объект. Оригинальный std::unique_ptr немедленно теряет это право собственности. Это гарантирует, что право собственности всегда принадлежит только одному std::unique_ptr.

Эквивалент boost::scoped_ptr в C ++ 11 - const std::unique_ptr. Это связано с тем, что его установка const предотвращает любое перемещение и, следовательно, не может быть передана собственность.

Простой способ увидеть, насколько важна семантика владения, - это на примере. Допустим, вы используете библиотеку злого разработчика, и в ней есть функция, о реализации которой вы не знаете, например:

cat* foo();

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

Однако теперь мудрый и добрый разработчик библиотеки напишет эту функцию так:

std::unique_ptr<cat> foo();

Так как это помогает? Что ж, std::unique_ptr говорит вам о многом. Он сообщает вам, что функция передает вам право владения объектом cat. cat теперь ваша исключительная ответственность. Это также очень полезно для того, чтобы дать вам умный указатель, потому что вам не нужно думать о delete его установке. Вы можете просто использовать указатель, и когда он выйдет за пределы области видимости, объект будет уничтожен. Или, если хотите, вы можете передать право собственности другой функции.

Это не означает, что только один указатель когда-либо будет владеть cat. Вам, как счастливому новому владельцу, решать, что будет дальше. Совершенно разумно решить, что вы хотите начать совместное владение своим cat:

std::unique_ptr<cat> up = foo();
std::shared_ptr<cat> sp(up.release());

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

Таким образом, boost::scoped_ptr немного похож на жадного cat собирателя, который никогда ни с кем не поделится cat, никогда никому не отдаст кошку и будет хранить ее до дня своей смерти.

person Joseph Mansfield    schedule 02.02.2013
comment
Это многое проясняет :) Большое спасибо! - person SandBag_1996; 02.02.2013