Set*_*eth 3 .net mixed-mode c++-cli wrapper shared-ptr
我目前正在使用C++/CLI包装一个C++类,用于.NET互操作性,遵循在托管类中保存本机指针的标准过程.在一个实例中,我有一个本机类,其功能如下:
std::shared_ptr<BaseChannel> channelData(const int RunNumber);
Run Code Online (Sandbox Code Playgroud)
我已经开始为它创建一个包装类BaseChannel
.但是,如果我将原始指针传递给托管类的构造函数,则无法保证托管类指向的对象的生命周期.即shared_ptr可能超出范围,对象将被删除,托管类将保留一个悬空指针.
这种情况的常见解决方案是什么?
UPDATE
@Ben:所以我在上面这个问题中包含了保存方法的类(假设它是在一个被调用的本机类中Node
,它被包装在一个名为NodeRef的托管类中:
ChannelUser^ NodeRef::ChannelData(int runNumber)
{
// mpNode is native class pointer of type Node held in managed class
// wrapper called NodeRef
std::shared_ptr<BaseChannel> spBaseChannel = mpNode->channelData(runNumber);
// ChannelUser is using clr_scoped_ptr to hold the shared_ptr
ChannelUser^ channelUser = gcnew ChannelUser(spBaseChannel);
return channelUser;
}
Run Code Online (Sandbox Code Playgroud)
因为shared_ptr没有增加引用计数,因为它通过引用传递给托管类,这是否意味着
只要此shared_ptr在范围内,它指向的对象仍然存在,因为它的引用计数至少为1
chi*_*tom 11
这是一个托管shared_ptr<T>
.您可以直接从a分配它shared_ptr
,它将获取一个副本,它将在管理对象被GC或处置时删除.
例子:
m_shared_ptr<CupCake> cupCake0(new CupCake());
m_shared_ptr<CupCake> cupCake1 = new CupCake();
m_shared_ptr<CupCake> cupCake2 = shared_ptr<CupCake>(new CupCake());
m_shared_ptr<CupCake> cupCake3 = make_shared<CupCake>();
shared_ptr<CupCake> cupCake4 = (shared_ptr<CupCake>)cupCake3;
Run Code Online (Sandbox Code Playgroud)
码:
#pragma once
#include <memory>
template <class T>
public ref class m_shared_ptr sealed
{
std::shared_ptr<T>* pPtr;
public:
m_shared_ptr()
: pPtr(new std::shared_ptr<T>())
{}
m_shared_ptr(T* t) {
pPtr = new std::shared_ptr<T>(t);
}
m_shared_ptr(std::shared_ptr<T> t) {
pPtr = new std::shared_ptr<T>(t);
}
m_shared_ptr(const m_shared_ptr<T>% t) {
pPtr = new std::shared_ptr<T>(*t.pPtr);
}
!m_shared_ptr() {
delete pPtr;
}
~m_shared_ptr() {
delete pPtr;
}
operator std::shared_ptr<T>() {
return *pPtr;
}
m_shared_ptr<T>% operator=(T* ptr) {
delete pPtr;
pPtr = new std::shared_ptr<T>(ptr);
return *this;
}
T* operator->() {
return (*pPtr).get();
}
void reset() {
pPtr->reset();
}
};
Run Code Online (Sandbox Code Playgroud)
shared_ptr
是本机类型,托管对象不能具有完整的本机子对象.
但是,正如您所注意到的,托管对象可以具有指向本机对象的指针.你需要的是一个指向a的指针shared_ptr
,它将被视为BaseChannel
对象的引用并防止它过早被释放.
当然,有很多理由使用智能指针而不是原始指针shared_ptr<BaseChannel>*
.我已经编写了一个适合的智能指针,您可以在codereview.stackexchange.com上找到它:"scoped_ptr for C++/CLI(确保托管对象正确释放拥有的本机对象)"
示例(未经过编译测试):
ref class ChannelUser
{
clr_scoped_ptr<shared_ptr<BaseChannel>> chan_ptr;
public:
ChannelUser( shared_ptr<BaseChannel>& chan ) : chan_ptr(new shared_ptr<BaseChannel>(chan)) {}
};
Run Code Online (Sandbox Code Playgroud)
这会自动实现IDisposable
并删除shared_ptr
何时Dispose
或终结器运行,从而减少对引用的引用计数BaseChannel
.
归档时间: |
|
查看次数: |
7689 次 |
最近记录: |