删除非类型化的共享\u ptr 我正在把一个C++库封装成一个C桥。
所有对象,我希望在堆上使用共享的ptr进行维护,如:删除非类型化的共享\u ptr 我正在把一个C++库封装成一个C桥。,c++,c++11,libstdc++,C++,C++11,Libstdc++,所有对象,我希望在堆上使用共享的ptr进行维护,如: void* makeFoo() { return new shared_ptr<void>(shared_ptr::make_shared<Foo>()); } void*makeFoo(){ 返回新的shared_ptr(shared_ptr::make_shared()); } 我可以使用这样的通用销毁: void destroy(void* p) { delete static_cast<sha
void* makeFoo() {
return new shared_ptr<void>(shared_ptr::make_shared<Foo>());
}
void*makeFoo(){
返回新的shared_ptr(shared_ptr::make_shared());
}
我可以使用这样的通用销毁:
void destroy(void* p) {
delete static_cast<shared_ptr<void>*> p;
}
void销毁(void*p){
删除静态_cast p;
}
或者有更简洁的方法吗?删除的参数类型必须与要删除的对象的实际类型相匹配(否则将如何调用正确的析构函数,例如?),或者至少是多态层次结构中的基本类型,这样就可以找到析构函数() 所以,不,你不能这样做。不。没有这样的“一般删除”
替代解决方案:您可以将
std::shared_ptr
插入到映射中,使用动态对象的地址作为键。解除分配功能可以从映射中删除共享指针 这里有两件事在起作用:
newsometype()
。。。然后您需要调用delete pointer
,其中pointer
具有typeSomeType*
,并指向该新表达式分配的对象。对于基类,这个规则有一些扩展,但是这里不涉及继承,所以我们就到此为止
shared_ptr
不仅管理Foo
对象,还管理一个知道如何销毁Foo
对象的“删除器”。当您从另一个构建一个shared\u ptr
时,该删除器将被传递。这允许“类型擦除”:
shared_ptr typed=make_shared();
shared_ptr erased=已键入;
在这里,erased
不再具有关于它指向的对象类型的编译时信息(该信息已“擦除”),但仍然具有关于对象类型的运行时信息(删除器)删除与新建分配的相同类型:a共享\u ptr
。这个shared_ptr
需要从一个shared_ptr
构建,因为它有一个知道如何销毁Foo
的删除器:
void*makeFoo(){
与_type=make_shared()共享的_ptr;
shared_ptr type_erased=with_type;//仅用于说明,合并到下面的行中!
返回新的共享_ptr(类型_擦除);
}
无效销毁(无效*ptr){
共享_ptr*原始_ptr=ptr;
删除原始ptr;
}
makeFoo
返回指向共享\u ptr
的指针。仅删除类型信息,即作为void*
destroy
假定它被传递了这样一个指针。它的delete调用shared\u ptr
的析构函数。由于shared_ptr
具有原始shared_ptr
的删除器,因此它知道如何实际销毁对象(Foo
)
旁注:OP的代码更改了很多次,但仍然有一些基本的语法错误。这是无效的C++!!
delete <shared_ptr<void>*> p;
删除p;
很抱歉没有提供替代方案,但这是一个比基本问题更广泛的主题;也许今天还有其他人有时间!shared_ptr维护一个用于销毁内部对象的删除器。所以你的答案是错误的。@user3612643 shared_ptr维护的内容是不相关的,因为触发其销毁的delete
语句从根本上被破坏了。@user3612643读到了@user3612643,这很有趣,但仍然是不相关的。OP根本没有共享\u ptr
。然而,他们却假装要删除他们所做的。它可以形成一个替代的(有效的)解决方案的基础,虽然我鼓励你去探索和写一个答案。我想你是说<代码>删除StasyType(P)< /C> >是的,现在已经固定了。不,还没有固定……你的最后一个编辑添加了更多无效的C++。为什么你总是把东西随机放在括号里?你上次的编辑完全改变了这一点。。。它包含了我在回答中提到的内容。但是您仍然没有解决destroy
中突出的语法问题。请不要做会改变问题重点的更改。是的,只要地图存储shared\ptr
s这是错误的。这当然有效。shared_ptr有一个记住类型的删除器。@DanielJour它没有错。同样,您也忽略了一点,即无论共享的ptr做什么,如果您传递了一个实际指向不相关的T2的T1*
,则程序具有未定义的行为。时期答案中的代码之所以有效,是因为您通过将指向T1
的正确T1*
传递给delete
@user3612643解决了这个问题,这基本上意味着我需要将它包装到维护deleter的某个结构中,该结构就是共享指针(如LR所澄清的,无效)。@user3612643 OP中没有解决方案。即使编译了它,我也会感到惊讶。没有涉及“子类型”。构造共享\u ptr
是一个很好的解决方案。本例中的代码有点浪费(删除类型的意义是什么?
只需将与新的共享\u ptr(…)
表达式中即可)但除此之外,这是一个很好的建议。是的;我已经详细说明了这些步骤:共享ptr构造、共享ptr类型擦除,使其成为动态分配的共享ptr不是等同于OP的makeFoo吗?不,因为您有一个指向共享ptr
…的指针,但您需要一个指向dest中共享ptr
的指针roy()
,您仍然需要键入输入void*
,然后才能删除它:void destroy(void*ptr){shared_