如何混合C++共享指针和对象引用

use*_*472 7 c++ objective-c shared-ptr grand-central-dispatch

我有以下代码Datum在Objective-C函数中使用类的C++对象work:

void work(const Datum &datum) {
    dispatch_async(dispatch_get_main_queue(), ^{
        // Work with datum.
    });
}
Run Code Online (Sandbox Code Playgroud)

使用实际为a的实例调用此代码boost::shared_ptr<Datum>,即

boost::shared_ptr<Datum> the_datum(new Datum());
work(*the_datum);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,实例可能the_datum会在块内部运行之前被释放work(对此执行dispatch_async异步操作datum的调用稍后执行;调用因此函数work立即返回).这显然会导致灾难.

一种解决方案可能是不传递引用work,而是传递引用boost::shared_ptr<Datum>.但是可能存在首选引用的情况,例如参见此线程.有没有办法保持接口work(即传递datum作为参考),但仍然阻止在块完成之前重新分配共享指针?

jxh*_*jxh 3

没有办法通过将接口保持work()不变并传入对 的引用来实现此目的datum。没有办法使用 来datum防止引用计数递减。考虑以下有缺陷的程序:

#include <memory>
int main () {
    std::shared_ptr<int> p1(new int);
    int &x = *p1;
    std::shared_ptr<int> p2(&x);
}
Run Code Online (Sandbox Code Playgroud)

此代码因双重释放而崩溃,因为shared_ptr<>控制结构不跟随指向对象的指针,而是跟随shared_ptr<>自身。

您可以做的是更改work()为采用 a shared_ptr(),但向传递到的块添加更多代码dispatch_async(),以便它可以使用该代码中的引用。由于您要将所有权转移给异步例程,unique_ptr<>因此您应该使用。我对 Objective-C 知之甚少,所以这个语法可能是错误的:

void work(std::unique_ptr<Datum> &datumptr_ref) {
    __block std::unique_ptr<Datum> datumptr(std::move(datumptr_ref));
    dispatch_async(dispatch_get_main_queue(), ^{
        Datum &datum = *datumptr
        // Work with datum.
    });
}
Run Code Online (Sandbox Code Playgroud)