scoped_ptr для C++/CLI для (обеспечения управляемого объекта надлежащим образом освобождает владеет собственный объект)


Мотивируя такой вопрос: есть ли в C++умный указатель проекта (например, scoped_ptr)?

Меня интересуют любые замечания рецензента, и особенно выявленные ошибки или несоответствия с родной шаблон scoped_ptr после чего этот код рисунком.

#pragma once

/** @file clr_scoped_ptr.h
 ** @author R Benjamin Voigt (richardvoigt@gmail.com)
 ** 
 ** Rights reserved.  This code is not public domain.
 ** 
 ** Licensed under CC BY-SA 3.0             http://creativecommons.org/licenses/by-sa/3.0/
 **             or Lesser GPL 3 or later    http://www.gnu.org/copyleft/lesser.html
 ** with the following restrictions (per GPL section 7):
 **  - all warranties are disclaimed, and if this is prohibited by law, your sole remedy shall be recovery of the price you paid to receive the code
 **  - derived works must not remove this license notice or author attribution
 **  - modifications must not be represented as the work of the original author
 **  - attribution is required in the "about" or "--version" display of any work linked hereto, or wherever copyright notices are displayed by the composite work
 **/

struct safe_bool { private: safe_bool(); };

/** \brief C++/CLI analogue to boost::scoped_ptr, also similar to std::unique_ptr, for management of the lifetime of an unmanaged class instance by a managed object
 **/
template<typename T>
public ref class clr_scoped_ptr
{
    T* m_native_ptr;

    // declare copy-constructors and assignment operators to prevent double-free
    clr_scoped_ptr( clr_scoped_ptr<T>% ) /* = delete */ { throw gcnew System::InvalidOperationException("clr_scoped_ptr is non-copyable"); }

    template<typename U>
    clr_scoped_ptr( clr_scoped_ptr<U>% ) { throw gcnew System::InvalidOperationException("clr_scoped_ptr is non-copyable"); }

    clr_scoped_ptr% operator=( clr_scoped_ptr<T>% ) /* = delete */ { throw gcnew System::InvalidOperationException("clr_scoped_ptr is non-copyable"); }

    template<typename U>
    clr_scoped_ptr% operator=( clr_scoped_ptr<U>% ) { throw gcnew System::InvalidOperationException("clr_scoped_ptr is non-copyable"); }

public:
    clr_scoped_ptr( void ) : m_native_ptr(nullptr) {}
    explicit clr_scoped_ptr( T* ptr ) : m_native_ptr(ptr) {}
    !clr_scoped_ptr( void ) { reset(); }
    ~clr_scoped_ptr( void ) { clr_scoped_ptr::!clr_scoped_ptr(); }

    template<typename U>
    clr_scoped_ptr( U ptr ) : m_native_ptr(ptr) {}

    void reset( T* ptr ) { delete m_native_ptr; m_native_ptr = ptr; }
    void reset( void ) { reset(nullptr); }

    clr_scoped_ptr% operator=( T* ptr ) { reset(ptr); }

    template<typename U>
    clr_scoped_ptr% operator=( U ptr ) { reset(ptr); }

    operator struct safe_bool*() { return reinterpret_cast<struct safe_bool*>(m_native_ptr); }

    void swap( clr_scoped_ptr<T>% other )
    {
        using std::swap;
        swap(m_native_ptr, other.m_native_ptr);
    }

    T* release( void ) { T* retval = m_native_ptr; m_native_ptr = nullptr; return retval; }
    T* get( void ) { return m_native_ptr; }

    static T* operator->( clr_scoped_ptr<T>% sptr ) { return sptr.get(); }
    static T& operator*( clr_scoped_ptr<T>% sptr ) { return *sptr.get(); }
};

template<typename T>
inline void swap( clr_scoped_ptr<T>% left, clr_scoped_ptr<T>% right )
{
    left.swap(right);
}


7547
19
задан 7 апреля 2011 в 03:04 Источник Поделиться
Комментарии
1 ответ

Я лишь поверхностно проверил код до сих пор, но это, кажется, имеет смысла. Однако, есть некоторые детали, где я что-то упускаю (что не удивило бы меня, я больше дома с C#) или код является более сложным, чем он должен быть. Любые комментарии приветствуются!


  • Частный конструкторы копирования и операторы присваивания исключения, хотя они и не могут называться. Разве это не достаточно, чтобы оставить их пустыми?

  • Конструктор и оператор присваивания оба принимают не только аргументы типа Т*, но и существовать в шаблонный вариант брать у*. Я не могу выяснить, почему. Моя первая мысль была, что это позволяет указателей на производные типы должны быть переданы; но опять же, это также возможно, используя только первая форма.

  • Аналогично, я не понимаю роли шаблона версии приватный конструктор и оператор присваивания. От моего понимания, ни один из этих будет сформирован автоматически, если вы не предоставите частных версиях.

  • Безопасный узор боол звучит как отличная идея (я сначала должен исследовать его). Однако, VS2010 показывает ошибку при компиляции, говоря: "не удается конвертировать из 'clr_scoped_ptr::оператор safe_bool *::safe_bool *' до 'safe_bool *'". Видимо, он рассматривает два вхождения ключевого слова struct safe_bool как двух различных типов. Я что-то пропустил?

  • Вы заканчиваете частных методов и операторов точкой с запятой, а вы пишите пустых списков аргументов как (недействительным) , а не (). Это просто стилистический выбор, или есть преимущества в этом?

6
ответ дан 9 апреля 2011 в 04:04 Источник Поделиться