删除非类型化的共享\u ptr 我正在把一个C++库封装成一个C桥。

删除非类型化的共享\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

所有对象,我希望在堆上使用共享的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<shared_ptr<void>*> p;
}
void销毁(void*p){
删除静态_cast p;
}

或者有更简洁的方法吗?

删除的参数类型必须与要删除的对象的实际类型相匹配(否则将如何调用正确的析构函数,例如?),或者至少是多态层次结构中的基本类型,这样就可以找到析构函数()

所以,不,你不能这样做。

不。没有这样的“一般删除”


替代解决方案:您可以将
std::shared_ptr
插入到映射中,使用动态对象的地址作为键。解除分配功能可以从映射中删除共享指针

这里有两件事在起作用:

  • 当您调用
    newsometype()
    。。。然后您需要调用
    delete pointer
    ,其中
    pointer
    具有type
    SomeType*
    ,并指向该
    新表达式分配的对象。对于基类,这个规则有一些扩展,但是这里不涉及继承,所以我们就到此为止

  • shared_ptr
    不仅管理
    Foo
    对象,还管理一个知道如何销毁
    Foo
    对象的“删除器”。当您从另一个构建一个
    shared\u ptr
    时,该删除器将被传递。这允许“类型擦除”:

    shared_ptr typed=make_shared();
    shared_ptr erased=已键入;
    
    在这里,
    erased
    不再具有关于它指向的对象类型的编译时信息(该信息已“擦除”),但仍然具有关于对象类型的运行时信息(删除器)

  • 因此,为了使这项工作,你需要确保你没有违反上述第1点;您需要
    删除
    新建
    分配的相同类型: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_