C++/CLI包装返回std::shared\u ptr的函数 我现在在C++中使用C++/CLI类来封装.NET的互操作性,这是在托管类中保存一个本地指针的标准过程。在一个实例中,我有一个本机类,其函数如下: std::shared_ptr<BaseChannel> channelData(const int RunNumber);
因为共享_ptr在通过引用传递给托管类时其引用计数没有增加,这是否意味着 只要这个共享的ptr在 范围,它指向的对象将 仍然存在,因为它的引用 计数将至少为1C++/CLI包装返回std::shared\u ptr的函数 我现在在C++中使用C++/CLI类来封装.NET的互操作性,这是在托管类中保存一个本地指针的标准过程。在一个实例中,我有一个本机类,其函数如下: std::shared_ptr<BaseChannel> channelData(const int RunNumber);,.net,c++-cli,wrapper,shared-ptr,mixed-mode,.net,C++ Cli,Wrapper,Shared Ptr,Mixed Mode,因为共享_ptr在通过引用传递给托管类时其引用计数没有增加,这是否意味着 只要这个共享的ptr在 范围,它指向的对象将 仍然存在,因为它的引用 计数将至少为1 ??(ref)共享\u ptr是本机类型,托管对象不能有完整的本机子对象 但是,正如您所注意到的,托管对象可以有指向本机对象的指针。您需要的是一个指向共享\u ptr的指针,该指针将作为对BaseChannel对象的引用,并防止其过早释放 当然,使用智能指针而不是原始的共享\u ptr*有很多原因。我写了一个智能指针,它应该是合适的,你可
??(ref)共享\u ptr是本机类型,托管对象不能有完整的本机子对象 但是,正如您所注意到的,托管对象可以有指向本机对象的指针。您需要的是一个指向
共享\u ptr
的指针,该指针将作为对BaseChannel
对象的引用,并防止其过早释放
当然,使用智能指针而不是原始的共享\u ptr*
有很多原因。我写了一个智能指针,它应该是合适的,你可以在codereview.stackexchange.com上找到它:
示例(未经编译测试):
ref类ChannelUser
{
clr_范围_ptr chan_ptr;
公众:
ChannelUser(shared_ptr&chan):chan_ptr(new shared_ptr(chan)){}
};
这会自动实现
IDisposable
,并在Dispose
或终结器运行时删除shared_ptr
,从而减少BaseChannel
上的引用计数。您可以直接从共享\u ptr
分配给它,它将获取一个副本,当托管对象被GC’d或disposed时,它将删除该副本
示例:
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;
m_shared_ptr cupCake0(new CupCake());
m_shared_ptr cupCake1=新纸杯蛋糕();
m_shared_ptr cupCake2=shared_ptr(new CupCake());
m_shared_ptr cupCake3=使_共享();
共享杯4=(共享杯3);
代码:
#pragma一次
#包括
模板
公共参考类m_共享\u ptr密封
{
std::共享的ptr*pPtr;
公众:
m_共享_ptr()
:pPtr(新std::shared_ptr())
{}
m_共享_ptr(T*T){
pPtr=新标准::共享ptr(t);
}
m_shared_ptr(标准::shared_ptr t){
pPtr=新标准::共享ptr(t);
}
m_共享\u ptr(常数m_共享\u ptr%t){
pPtr=新标准::共享ptr(*t.pPtr);
}
!m_共享_ptr(){
删除pPtr;
}
~m_共享_ptr(){
删除pPtr;
}
操作员std::共享的_ptr(){
返回*pPtr;
}
m_共享_ptr%运算符=(T*ptr){
删除pPtr;
pPtr=新标准::共享ptr(ptr);
归还*这个;
}
T*运算符->(){
return(*pPtr.get();
}
无效重置(){
pPtr->reset();
}
};
+1-你能提供一个如何在你的回答中使用你的clr\u scoped\u ptr
的例子吗?@Seth:已经完成了,希望这有帮助。如果发现任何重大错误,请告诉我。引用计数会增加(一次是通过ChannelUser ctor初始值设定项中的spBaseChannel
的构造函数增加,一次是通过new shared_ptr
增加)。。。但是当std::shared_ptr
不是线程安全时,这些东西就不会是线程安全的。@Ben:我更新了最后一个问题,以恰当地表示我的担忧。然而,我认为你在之前的评论中已经回答了这个问题。ChannelUser ctor-initializer.awesome答案中的ref计数器增加。被低估了。m_shared_ptr的赋值运算符没有先删除p,这不是内存泄漏吗?我想你是对的,请随意编辑并修复这个答案。我想出了一些我需要的附加方法://用于访问共享_ptr成员,如'use_count'const std::shared_ptr&get(){return*pPtr;}//当传递到另一个托管对象std::shared_ptr*share(){return new std::shared_ptr(*pPtr)}时非常有用//允许通过std::make_shared m_ptr%operator=(const std::shared_ptr&t){delete pPtr pPtr=new std::shared_ptr(t);return*this;}~
Brilliant本人就要写这样的东西了。谢谢你为我节省了一些时间!:D
ref class ChannelUser
{
clr_scoped_ptr<shared_ptr<BaseChannel>> chan_ptr;
public:
ChannelUser( shared_ptr<BaseChannel>& chan ) : chan_ptr(new shared_ptr<BaseChannel>(chan)) {}
};
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;
#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();
}
};