首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++/CLI的scoped_ptr (确保托管对象适当释放拥有的本机对象)

C++/CLI的scoped_ptr (确保托管对象适当释放拥有的本机对象)
EN

Code Review用户
提问于 2011-04-07 03:27:29
回答 3查看 9.7K关注 0票数 19

激发这样的问题:(_ptr)是否有C++/CLI智能指针项目(例如,限定作用域)?

我对任何审阅者的评论都感兴趣,特别是发现了与本机scoped_ptr模板不一致的bug或不一致之处,在此模板之后,这段代码就形成了模式。

代码语言:javascript
复制
#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);
}
EN

回答 3

Code Review用户

回答已采纳

发布于 2011-04-09 16:39:37

到目前为止,我只对代码进行了表面测试,但这似乎是有意义的。但是,在有些细节中,我要么遗漏了一些东西(这并不让我感到惊讶,因为我更喜欢使用C#),要么代码比它所需要的更复杂。如有任何意见,敬请见谅!

  • 私有副本构造函数和赋值运算符抛出异常,尽管它们永远不会被调用。让它们空着不就够了吗?
  • 构造函数和赋值操作符不仅接受T*类型的参数,而且在采用U*的模板版本中也存在。我不太明白为什么。我的第一个想法是,这允许传递指向派生类型的指针;但同样,这也可以使用第一种形式。
  • 类似地,我不理解私有构造函数和赋值操作符的模板版本的作用。根据我的理解,如果不提供私有版本,这两个版本都不会自动生成。
  • 安全的bool模式听起来像是一个好主意(我首先必须研究它)。但是,VS2010显示了一个编译错误,它说“不能从'clr_scoped_ptr<T>::operator safe_bool *::safe_bool *‘转换为'safe_bool *'”。显然,它将struct safe_bool的两次出现作为两种不同的类型。我是不是漏掉了什么?
  • 以分号结束私有方法和运算符,然后将空参数列表作为(void)而不是()写入。这些只是风格上的选择,还是这样做有好处?
票数 7
EN

Code Review用户

发布于 2014-07-04 21:02:55

您可以将operator=声明为返回一个clr_scoped_ptr%,但是在它们的正文中没有返回语句。这给了我编译错误。我认为实现应该是:

代码语言:javascript
复制
clr_scoped_ptr% operator=( T* ptr ) { reset(ptr); return (clr_scoped_ptr%)this; } 

template<typename U>
clr_scoped_ptr% operator=( U ptr ) { reset(ptr); return (clr_scoped_ptr%)this; }
票数 3
EN

Code Review用户

发布于 2014-07-07 14:21:25

我还要补充的是,复制构造函数和赋值操作符应该抛出NotSupportedException而不是InvalidOperationException。后者应该依赖于对象状态。

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/1695

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档