容器对象作为 (void*) 传递时的共享指针行为
shared pointer behavior when container object passed as (void*)
我的 class 对象 (ObjA) 中有 shared_ptr 变量。要求将此对象存储为另一个 Class' 对象 (ObjB) 的 (void*) 实体。
我的问题是,shared_ptr 的行为是什么(关联的堆内存会被释放吗?它的引用计数会怎样?)-
ObjA转void时*
当 ObjB 的 void* 实体被转换回 (ClassA *)
简化代码:
Class AA{
shared_ptr<int> aptr;
public:
AA(){
aptr = make_shared<int>(100);
}
shared_ptr<int> get_aptr(){
return aptr;
}
};
Class BB{
void *smpl;
public:
void setter(void* p){
smpl = p;
}
void* getter(){
return smpl;
}
};
int main(){
AA *objA = new AA();
BB *objB = new BB();
objB->setter(objA);
//status of allocated int in class AA here?
//some code later
AA *objA_2 = (AA*)objB->getter();
//status of allocated int in class AA here?
shared_ptr<int> p2 = objA_2->get_aptr();
//is this allowed
}
我最关心的是 - 如何释放 shared_ptr 的内存。 (鉴于它包含在 void* 对象中,无法删除 - shared_ptr 始终保留在范围内)
我试图删除 objB,并在 destructor-
中对其组件 void* 进行适当的转换
BB::~BB(){
delete (*AA)smpl;
}
但这给出了错误,因为 class 中的 shared_ptr 变量 AA 不允许显式删除 - 它仅在超出范围时释放其分配的区域。 (在这种情况下,它永远不知道什么时候超出范围!)
还有,classBB是第三方的class-我不能修改smpl成员变量的类型void*(节点class中的_userData变量,Cocos2dx中)。
请帮助解决此内存泄漏..
这里的void *
充当了一个观察指针。它根本不影响共享指针,因为共享指针甚至不知道指向其包含对象的原始指针的存在。
如果您选择 shared_ptr<void>
而不是原始指针(并通过原始共享指针构造它,即您的 setter 应该被 void setter(std::shared_ptr<void> const& p)
替换,那将会有所不同例如)。
在这种情况下,引用计数会受到影响,指向的对象的生存将得到保证。关于此选项,请参阅 here.
编辑:从您的评论来看,您似乎正在寻找类似于以下内容的设置:
struct AA
{
//...
};
struct BB
{
std::shared_ptr<void> smpl;
void setter(std::shared_ptr<void> const& p)
{
smpl = p; //now the ref count of your shared_tr to AA is increased
}
};
int main()
{
auto objA = std::make_shared<AA>();
auto objB = std::make_shared<BB>();
objB->setter(objA);
std::cout<<objA.use_count()<<std::endl; //prints "2"
}
调用setter后的引用计数为2
。 shared_ptr<void>
就像一个普通的共享指针一样,它使 AA
-object 保持活动状态,或者如果指针超出范围(它本身就是最后一个指向给定的对象),则正确地销毁它的对象AA
).
这行得通,因为原始共享指针的删除器已被复制,知道由谁进行销毁。
EDIT2: 回答 OP 代码中的问题:
objB->setter(objA);
//status of allocated int in class AA here?
AA
中的共享指针完全不受影响。
//some code later
AA *objA_2 = (AA*)objB->getter();
//status of allocated int in class AA here?
同样,共享指针不受影响。然而,这一步需要小心:如果原始对象不再存在,您将得到一个悬挂指针。因此,最好使用共享指针。
shared_ptr<int> p2 = objA_2->get_aptr();
//is this allowed
如果指针有效,当然可以。
我不明白的一件事是为什么你在 class 内部使用智能指针,而在外部使用原始指针。这有什么原因吗?
我的 class 对象 (ObjA) 中有 shared_ptr 变量。要求将此对象存储为另一个 Class' 对象 (ObjB) 的 (void*) 实体。
我的问题是,shared_ptr 的行为是什么(关联的堆内存会被释放吗?它的引用计数会怎样?)-
ObjA转void时*
当 ObjB 的 void* 实体被转换回 (ClassA *)
简化代码:
Class AA{
shared_ptr<int> aptr;
public:
AA(){
aptr = make_shared<int>(100);
}
shared_ptr<int> get_aptr(){
return aptr;
}
};
Class BB{
void *smpl;
public:
void setter(void* p){
smpl = p;
}
void* getter(){
return smpl;
}
};
int main(){
AA *objA = new AA();
BB *objB = new BB();
objB->setter(objA);
//status of allocated int in class AA here?
//some code later
AA *objA_2 = (AA*)objB->getter();
//status of allocated int in class AA here?
shared_ptr<int> p2 = objA_2->get_aptr();
//is this allowed
}
我最关心的是 - 如何释放 shared_ptr 的内存。 (鉴于它包含在 void* 对象中,无法删除 - shared_ptr 始终保留在范围内) 我试图删除 objB,并在 destructor-
中对其组件 void* 进行适当的转换BB::~BB(){
delete (*AA)smpl;
}
但这给出了错误,因为 class 中的 shared_ptr 变量 AA 不允许显式删除 - 它仅在超出范围时释放其分配的区域。 (在这种情况下,它永远不知道什么时候超出范围!)
还有,classBB是第三方的class-我不能修改smpl成员变量的类型void*(节点class中的_userData变量,Cocos2dx中)。 请帮助解决此内存泄漏..
这里的void *
充当了一个观察指针。它根本不影响共享指针,因为共享指针甚至不知道指向其包含对象的原始指针的存在。
如果您选择 shared_ptr<void>
而不是原始指针(并通过原始共享指针构造它,即您的 setter 应该被 void setter(std::shared_ptr<void> const& p)
替换,那将会有所不同例如)。
在这种情况下,引用计数会受到影响,指向的对象的生存将得到保证。关于此选项,请参阅 here.
编辑:从您的评论来看,您似乎正在寻找类似于以下内容的设置:
struct AA
{
//...
};
struct BB
{
std::shared_ptr<void> smpl;
void setter(std::shared_ptr<void> const& p)
{
smpl = p; //now the ref count of your shared_tr to AA is increased
}
};
int main()
{
auto objA = std::make_shared<AA>();
auto objB = std::make_shared<BB>();
objB->setter(objA);
std::cout<<objA.use_count()<<std::endl; //prints "2"
}
调用setter后的引用计数为2
。 shared_ptr<void>
就像一个普通的共享指针一样,它使 AA
-object 保持活动状态,或者如果指针超出范围(它本身就是最后一个指向给定的对象),则正确地销毁它的对象AA
).
这行得通,因为原始共享指针的删除器已被复制,知道由谁进行销毁。
EDIT2: 回答 OP 代码中的问题:
objB->setter(objA);
//status of allocated int in class AA here?
AA
中的共享指针完全不受影响。
//some code later
AA *objA_2 = (AA*)objB->getter();
//status of allocated int in class AA here?
同样,共享指针不受影响。然而,这一步需要小心:如果原始对象不再存在,您将得到一个悬挂指针。因此,最好使用共享指针。
shared_ptr<int> p2 = objA_2->get_aptr();
//is this allowed
如果指针有效,当然可以。
我不明白的一件事是为什么你在 class 内部使用智能指针,而在外部使用原始指针。这有什么原因吗?