2016-11-07 69 views
0

我需要为共享指针实例编写我自己的析构函数。不幸的是,这样的实例是从库函数调用中获得的,并不是我初始化它的。那么我怎么能在这里“设置”析构函数呢?如何为现有的共享指针设置删除器?

理想的情况下,在我脑海里的代码可能看起来像

pointer.setDeleter(myDeleter); 

pointer = std::make_shared<MyType>(pointerOld.get(), myDeleter); 

我没有找到的第一个假设的API。对于第二个,据说MyType没有带2个参数的构造函数。它不可编译。

对此有何想法?

谢谢!

+0

为什么你想要这个?据推测,图书馆不希望你与他们的删除者搞砸。 – GManNickG

+0

@GManNickG因为我正在使用具有事件库机制的库。因此,我希望在某个线程(即事件库的线程)中调用删除器。否则,删除者将引入段错误。 – zzy

+0

您是否需要在释放对共享指针的最后一个引用时调用删除器,或者是否足以创建一个新的共享指针(具有其自己的生存期),该共享指针延长了源共享指针的生命周期,去零,运行额外的代码? – Yakk

回答

1

这是我能得到的最接近的。

template<class T> 
std::shared_ptr<T> extra_deleter(std::shared_ptr<T> in, std::function<void(T*)> action) { 
    if (!in) return {}; 
    if (!action) return std::move(in); 
    // action=std::move(action) in c++14 
    auto new_deleter = [action](std::shared_ptr<T>* tin) { 
     action(tin->get()); 
     delete tin; 
    }; 

    auto tmp = std::shared_ptr<std::shared_ptr<T>>(
    new shared_ptr<T>(std::move(in)), 
    std::move(new_deleter) 
); 
    if (!tmp) return {}; 
    // aliasing ctor: 
    return {tmp, tmp.get()->get()}; 
} 

此创建一个共享指针共享指针,以定制删除动作增强它,然后使用别名构造函数创建一个共享的指针T.

这不会导致额外的代码运行时来源shared_ptr被销毁。相反,它会创建一个新的shared_ptr,其中包含额外的销毁代码。当新的血统shared_ptr死亡时,运行action

如果没有其他原始shared_ptr状态的其他引用,则运行shared_ptr的原始驱逐程序。

+0

对不起,我没有完全明白你的想法 - 我对C++ 11相对来说比较陌生。你能告诉我如何调用这个函数(特别是当删除器是一个类的非静态成员函数时(实际上所有这些东西都在一个类中))?另外,我不理解最后的返回语句:为什么我们在** curly **括号中有这两个参数? – zzy

+0

@zzy传递一个lambda的'T *'作为'action',就像'[](T * foo){std :: cout <<(void *)foo <<'\ n';}'打印指针值。作为第一个参数传递'shared_ptr '。它返回一个扩充的共享ptr,当它的引用计数到期时,它会调用该操作。然后它放弃源shared_ptr上的引用计数。它仍然指向相同的“T”。 'return {a,b};'是用'a,b'直接调用返回值的ctor的方法。原始的共享ptr状态不会被修改。 – Yakk