我已经习惯了C++ RAII工具,我想以正确的方式使用RAII和C++/CLI中的托管代码.Herb Sutter和微软都告诉我这是最好的做法.
我有这样的事情:
ref struct Managed
{
// No default constructor
Managed( /*...*/ ) { /*...*/ }
~Managed() { /* Important non-managed resource release here */ }
// ...
};
ref struct UsesManaged
{
Managed^ m_;
array<Managed^>^ a_;
UsesManaged( Managed^ m, array<Managed^>^ a ) : m_(m), a_(a) {}
// ...
};
ref struct Creator
{
Managed^ m_;
array<Managed^>^ a_;
UsesManaged^ u_;
Creator()
{
// Must allocate dynamically here, not in initializer list
// because in …Run Code Online (Sandbox Code Playgroud) 我目前正在使用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