将Qt对象与std :: shared_ptr一起使用

时间:2012-06-09 17:53:27

标签: c++ qt shared-ptr

我正在尝试将一个小型实用程序应用程序更新为更现代的C ++方式,但是我在使用std :: shared_ptr的一些Qt对象时遇到了问题,特别是那些接收其他QWidget作为构造函数参数的那些。

例如:

private:
    std::shared_ptr<QWidget> centralwidget;
    std::shared_ptr<QVBoxLayout> verticalLayout;

public:
    void setupUi(QMainWindow *MainWindow) // this pointer is a .get() from a shared_ptr
    {
        centralwidget = std::make_shared<QWidget>(new QWidget(MainWindow)); // compiles fine
        verticalLayout = std::make_shared<QVBoxLayout>(new QVBoxLayout(centralwidget.get())); // does not compile
    }

编译错误是:

  

错误1错误C2664:'QVBoxLayout :: QVBoxLayout(QWidget *)':不能   将参数1从'QVBoxLayout *'转换为'QWidget *'e:\ microsoft   visual studio 11.0 \ vc \ include \ memory 855

我似乎无法理解这个错误,我没有转换任何东西,我只是想创建一个QVBoxLayout对象并将QWidget作为其父对象传递(就像我会用原始指针做的那样)。

2 个答案:

答案 0 :(得分:8)

一般情况下,我尝试避免将shared_ptr用于Qt GUI对象,因为Qt已经提供了自己的内存管理机制。每个QObject可能都有一个父对象,当这个父对象死亡时,他会删除它的所有子对象。这里不需要shared_pointer,也没有给你任何附加值:你可以完美地使用原始指针而不会造成内存泄漏。

一般来说,如果QObject的父节点在删除最后一个shared_ptr实例之前就已经死掉,那么很快就会遇到麻烦,因为当最后一个shared_ptr被销毁时,该对象将被第二次删除。这不是这种情况,但要小心:)

答案 1 :(得分:4)

std::make_shared的参数将传递给您要实例化的类的构造函数。所以基本上你所做的就等同于:

new QVBoxLayout(new QVBoxLayout(centralwidget.get()))

我认为你要做的是:

centralwidget = std::make_shared<QWidget>(MainWindow);
verticalLayout = std::make_shared<QVBoxLayout>(centralwidget.get());

查看std::make_shared的文档(例如here)。这个函数的重点是在内存中的对象实例附近分配引用计数,所以你必须让它为你做分配。