本机智能指针变量的 c++/cli 包装器 class
c++/cli wrapper for variable of native smart-pointer class
我是 C# 和 C++/CLI 的新手,对它们不是很熟悉。我进行了搜索,但找不到一个非常简单的事情的现有解决方案(我想这应该很常见)。
我正在编写一个简单的 C++/CLI 项目(C# 中使用的 C++ 本机 dll 的包装器)。有很多示例如何为本机编写包装器 class:
class CNativeClass {
CNativeClass() {}
void Foo() {}
}
public ref class CNativeClassWrapper {
public:
CNativeClassWrapper() {
_Wrapper = new CNativeClass;
}
~CNativeClassWrapper() {
this->!CNativeClassWrapper();
}
!CNativeClassWrapper() {
delete _Wrapper;
_Wrapper = nullptr;
}
void Foo() {
_Wrapper->Foo();
}
private:
CNativeClass* _Wrapper;
}
这是简化的示例代码。可能有更多原生 classes,可能有延迟初始化...很多次要但必要的代码。
原生 class 的变量 是否有隐藏所有这些细节的 包装器?
就像纯 C++ 中的智能指针模板。
此外,
如果本机 class 实际上是一个智能指针(我 90% 的情况下,我们使用 boost::shared_ptr<>),代码就会变得一团糟:
- 检查可以是
if ( _Wrapper )
或if ( *_Wrapper )
甚至if ( _Wrapper && *_Wrapper )
,
- 访问方法
(*_Wrapper)->Foo();
、
- 如何重置?
(*_Wrapper).reset();
和 _Wrapper->reset();
都正确,但太混乱了。
有人知道这个的解决方案吗?
我认为 C++/CLI 框架没有内置 class,但您可以轻松设计自己的。
看看这个问题:auto_ptr or shared_ptr equivalent in managed C++/CLI classes
我不会使用智能指针。当包含托管 class 被处置或完成时,本机对象的托管包装器将负责释放本机对象。
好吧,我终于找到了这样的包装纸类:
持有一般原生类:
template <class T>
public ref class native_auto_ptr
{
public:
native_auto_ptr()
{
_pNative = new T;
}
native_auto_ptr(const native_auto_ptr<T>% rhs)
{
_pNative = new T( *rhs._pNative );
}
~native_auto_ptr()
{
reset();
}
void reset()
{
delete _pNative;
_pNative = nullptr;
}
T* ptr()
{
return _pNative;
}
T* operator->()
{
return _pNative;
}
operator bool()
{
return _pNative;
}
void operator=(const native_auto_ptr<T>% rhs)
{
*_pNative = *rhs._pNative;
}
void operator=(const T% rhs)
{
*_pNative = rhs;
}
protected:
!native_auto_ptr()
{
reset();
}
private:
T* _pNative;
};
持有shared_ptr<>
:
template <class T>
public ref class native_shared_ptr
{
public:
native_shared_ptr()
{
_spNative = new boost::shared_ptr<T>;
}
native_shared_ptr(const native_shared_ptr<T>% rhs)
{
_spNative = new boost::shared_ptr<T>;
*this = rhs;
}
native_shared_ptr(const boost::shared_ptr<T>% rhs)
{
_spNative = new boost::shared_ptr<T>( rhs );
}
~native_shared_ptr()
{
reset();
}
void reset()
{
delete _spNative;
_spNative = nullptr;
}
T* operator->()
{
return _spNative->get();
}
operator bool()
{
return _spNative && *_spNative;
}
void operator=(const native_shared_ptr<T>% rhs)
{
*_spNative = *rhs._spNative;
}
void operator=(const boost::shared_ptr<T>% rhs)
{
*_spNative = rhs;
}
protected:
!native_shared_ptr()
{
reset();
}
private:
boost::shared_ptr<T>* _spNative;
};
我很开心:)
- 他们隐藏了 new/delete 个职位。
- 他们很安全。
- 它们的语法接近普通的智能指针,方便。
唯一的问题是带有参数的 ctors...(待定)
我是 C# 和 C++/CLI 的新手,对它们不是很熟悉。我进行了搜索,但找不到一个非常简单的事情的现有解决方案(我想这应该很常见)。
我正在编写一个简单的 C++/CLI 项目(C# 中使用的 C++ 本机 dll 的包装器)。有很多示例如何为本机编写包装器 class:
class CNativeClass {
CNativeClass() {}
void Foo() {}
}
public ref class CNativeClassWrapper {
public:
CNativeClassWrapper() {
_Wrapper = new CNativeClass;
}
~CNativeClassWrapper() {
this->!CNativeClassWrapper();
}
!CNativeClassWrapper() {
delete _Wrapper;
_Wrapper = nullptr;
}
void Foo() {
_Wrapper->Foo();
}
private:
CNativeClass* _Wrapper;
}
这是简化的示例代码。可能有更多原生 classes,可能有延迟初始化...很多次要但必要的代码。
原生 class 的变量 是否有隐藏所有这些细节的 包装器? 就像纯 C++ 中的智能指针模板。
此外, 如果本机 class 实际上是一个智能指针(我 90% 的情况下,我们使用 boost::shared_ptr<>),代码就会变得一团糟:
- 检查可以是
if ( _Wrapper )
或if ( *_Wrapper )
甚至if ( _Wrapper && *_Wrapper )
, - 访问方法
(*_Wrapper)->Foo();
、 - 如何重置?
(*_Wrapper).reset();
和_Wrapper->reset();
都正确,但太混乱了。
有人知道这个的解决方案吗?
我认为 C++/CLI 框架没有内置 class,但您可以轻松设计自己的。
看看这个问题:auto_ptr or shared_ptr equivalent in managed C++/CLI classes
我不会使用智能指针。当包含托管 class 被处置或完成时,本机对象的托管包装器将负责释放本机对象。
好吧,我终于找到了这样的包装纸类:
持有一般原生类:
template <class T> public ref class native_auto_ptr { public: native_auto_ptr() { _pNative = new T; } native_auto_ptr(const native_auto_ptr<T>% rhs) { _pNative = new T( *rhs._pNative ); } ~native_auto_ptr() { reset(); } void reset() { delete _pNative; _pNative = nullptr; } T* ptr() { return _pNative; } T* operator->() { return _pNative; } operator bool() { return _pNative; } void operator=(const native_auto_ptr<T>% rhs) { *_pNative = *rhs._pNative; } void operator=(const T% rhs) { *_pNative = rhs; } protected: !native_auto_ptr() { reset(); } private: T* _pNative; };
持有
shared_ptr<>
:template <class T> public ref class native_shared_ptr { public: native_shared_ptr() { _spNative = new boost::shared_ptr<T>; } native_shared_ptr(const native_shared_ptr<T>% rhs) { _spNative = new boost::shared_ptr<T>; *this = rhs; } native_shared_ptr(const boost::shared_ptr<T>% rhs) { _spNative = new boost::shared_ptr<T>( rhs ); } ~native_shared_ptr() { reset(); } void reset() { delete _spNative; _spNative = nullptr; } T* operator->() { return _spNative->get(); } operator bool() { return _spNative && *_spNative; } void operator=(const native_shared_ptr<T>% rhs) { *_spNative = *rhs._spNative; } void operator=(const boost::shared_ptr<T>% rhs) { *_spNative = rhs; } protected: !native_shared_ptr() { reset(); } private: boost::shared_ptr<T>* _spNative; };
我很开心:)
- 他们隐藏了 new/delete 个职位。
- 他们很安全。
- 它们的语法接近普通的智能指针,方便。
唯一的问题是带有参数的 ctors...(待定)