简体   繁体   English

如何防止删除用作共享指针的原始指针?

[英]How to prevent deletion of a raw pointer that is used as shared pointer?

I implemented a C-API for a C++ class which uses shared-pointers of other objects to access them. 我为C ++类实现了C-API,该类使用其他对象的共享指针来访问它们。 In my C-API I can of course only get raw pointers. 在我的C-API中,我当然只能获得原始指针。 So I "convert" the raw pointer in my C-API to a shared-pointer and use this then with my C++ class methods: 因此,我将C-API中的原始指针“转换”为共享指针,然后将其与我的C ++类方法一起使用:

method(std::shared_ptr<dataType>(raw-pointer));

Now I have the problem that at the end of "method" always the shared-pointer destructor is called and it unfortunately kills the object my raw-pointer is pointing at (which I don't want). 现在,我遇到的问题是,在“方法”的末尾,总是会调用共享指针析构函数,并且不幸的是,它杀死了我的原始指针指向的对象(我不想要)。 So, how can I prevent the raw-pointer from being killed? 因此,如何防止原始指针被杀死?

I already tried shared-pointer functions like reset() or swap(), but they all didn't let my raw-pointer go... 我已经尝试过像reset()或swap()这样的共享指针功能,但是它们都没有让我的原始指针走...

bool Traffic_doStep(traffic_handle t, environment_handle e, double cycletime) {
    if (!valid(t, __FUNCTION__)) return false;
    if (!valid(e, __FUNCTION__)) return false;
    if (!valid(cycletime, __FUNCTION__)) return false;

    try {
        t->doStep(std::shared_ptr<Environment>(e), cycletime);
        return true;
    }
    catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return false;
    }
}

Expected result would be that the raw-pointer e is still pointing to a valid object after this function returned. 预期的结果是,此函数返回后,原始指针e仍指向有效对象。 Actually the raw-pointer points then to a deleted object. 实际上,原始指针然后指向已删除的对象。

Don't put the pointer in a std::shared_ptr 不要将指针放在std::shared_ptr

The purpose of Smart Pointers in C++ is to provide automatic Lifetime management. C ++中的智能指针的目的是提供自动的生命周期管理。 When you write std::shared_ptr<int> ptr{raw_ptr}; 当您编写std::shared_ptr<int> ptr{raw_ptr}; , the expectation is that when ptr goes out of scope, the object pointed to by raw_ptr will be delete 'd. ,期望是当ptr超出范围时, raw_ptr指向的对象将被delete If this is not the intent, then you should not be placing the pointer in a smart pointer. 如果这不是目的,则不应将指针放在智能指针中。

So if your application does not manage the lifetime of a pointer, then it is perfectly acceptable to store a raw pointer. 因此,如果您的应用程序无法管理指针的生存期,那么存储原始指针是完全可以接受的。

If the API behind the function cannot be altered, you will instead need to construct the std::shared_ptr with a no-op deleter function, so that when clean-up is called, nothing will happen to the pointer. 如果该函数后面的API无法更改,则将需要使用无操作删除器函数构造std::shared_ptr ,以便在调用清理时指针不会发生任何变化。

try {
    std::shared_ptr<Environment> temp_ptr{e, [](int *) {}/*No-Op Deleter*/};
    t->doStep(temp_ptr, cycletime);
    return true;
}

This will solve your problem, but this is, of course, an Antipattern; 这将解决您的问题,但这当然是反模式; don't do this unless you've been forced to by API design constraints that you cannot control. 除非您因无法控制的API设计约束而被迫这样做,否则请不要这样做。

You may provide a custom deleter of a shared pointer. 您可以提供共享指针的自定义删除器。

Here is a viable constructor: 这是一个可行的构造函数:

template< class Y, class Deleter > 
shared_ptr( Y* ptr, Deleter d );

But I would rather use a unique pointer and then release it. 但是我宁愿使用唯一的指针然后释放它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM