取消引用共享指针并按引用调用

Dereferencing shared pointer and call by reference

我使用 QMapControl 的一些分支并发现了一个错误。 GeometryPointImage 有 getter 图像 const QPixmap& image() const:

const QPixmap& GeometryPointImage::image() const
{
    // Is the image pixmap currently null?
    if (m_image == nullptr) { //std::shared_ptr<QPixmap> m_image;
        // Have we already constructed the null image pixmap?
        if (m_image_null == nullptr) { //std::unique_ptr<QPixmap> m_image_null;
            // Construct the null image pixmap.
            m_image_null.reset(new QPixmap);
        }
        // Return the null image pixmap.
        return *(m_image_null.get());
    } else {
        // Return the image pixmap.
        return *(m_image.get());
    }
}

m_image有多种setter,image()getter用在draw()函数中:

painter.drawPixmap(-pixmap_rect_px.rawRect().width() / 2.0, -pixmap_rect_px.rawRect().height() / 2.0, image()); // void drawPixmap(int x, int y, const QPixmap &pm)

我可以捕捉到这样的行为:draw() 函数调用 image() 取消引用共享指针,它进入 drawPixmap 和其他一些事件调用 setImage() 其中 m_image 分配给新值,共享指针的析构函数析构 drawPixmap() 引用的 QPixmap 对象,然后应用程序进入 SIGSEGV。

我认为 getter return 对共享指针所拥有的东西的引用不是这样好的做法,但是最合适的解决方案是什么?我不想复制 QPixMap 对象或将互斥体添加到 getter、setter 和 draw() 中。有没有办法延长引用对象的寿命(可能类似于 qAsConst )?应该 getter return std::shared_ptr<QPixmap>?

更新: 详细信息:setImage() 从主线程调用,此 setter 预计会发出信号以重绘对象。但是 QMapControl main class 也使用 QtConcurrent::run() 重绘整个场景,并且它涉及其他线程的像素图。并且线程 #1 在线程例如删除对象时删除对象。 #6(或#7)做 drawPixmap().

好吧,我不希望现在有人对这个问题给出另一个答案,所以让我的解决方案,它可能会帮助以后遇到这种问题的人:

std::shared_ptr<QPixmap> GeometryPointImage::image() const
{
    // Is the image pixmap currently null?
    if (m_image == nullptr)
    {
        // Have we already constructed the null image pixmap?
        if (m_image_null == nullptr)
        {
            // Construct the null image pixmap.
            m_image_null.reset(new QPixmap);
        }

        // Return the null image pixmap.
        return std::make_shared<QPixmap>(*m_image_null.get());
    }
    else
    {
        // Return the image pixmap.
        return m_image;
    }
}

....

painter.drawPixmap(-pixmap_rect_px.rawRect().width() / 2.0, -pixmap_rect_px.rawRect().height() / 2.0, *image());

现在,返回 shared_ptr 会延长 QPixMap 的生命周期,即使它已被其他东西重置。此外,image() 方法仅在 class 中使用,没有从外部使用,因此很容易解决此问题。