Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Qt&;共享_指针:执行错误_C++_Qt_Shared Ptr_Smart Pointers - Fatal编程技术网

C++ Qt&;共享_指针:执行错误

C++ Qt&;共享_指针:执行错误,c++,qt,shared-ptr,smart-pointers,C++,Qt,Shared Ptr,Smart Pointers,我正在尝试使用tr1的shared\u ptr和Qt 4.8.2,但我遇到了一些麻烦。 这是我的代码: #include "mainwindow.h" #include "ui_mainwindow.h" #include <string> #include <tr1/memory> using namespace std::tr1; #include <QHBoxLayout> #include <QVBoxLayout> #include &

我正在尝试使用tr1shared\u ptrQt 4.8.2,但我遇到了一些麻烦。 这是我的代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <string>
#include <tr1/memory>
using namespace std::tr1;

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QTreeView>
#include <QListView>
#include <QWidget>

#include <iostream>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    shared_ptr<QHBoxLayout> mainLayout(new QHBoxLayout);

    shared_ptr<QTreeView> mainFeeds(new QTreeView);

    mainLayout->addWidget(mainFeeds.get());
    shared_ptr<QWidget> mainWidget (new QWidget);
    mainWidget->setLayout(mainLayout.get()); // <--- this line

    shared_ptr<QWidget> rightWidget(new QWidget);
    shared_ptr<QVBoxLayout> rightLayout(new QVBoxLayout);

    shared_ptr<QListView> rightItems(new QListView);
    rightLayout->addWidget(rightItems.get());

    shared_ptr<QListView> rightPreview(new QListView);
    rightLayout->addWidget(rightPreview.get());

    rightWidget->setLayout(rightLayout.get());
    mainLayout->addWidget(rightWidget.get());

    this->setCentralWidget(mainWidget.get());
}

MainWindow::~MainWindow()
{
    delete ui;
}
#包括“mainwindow.h”
#包括“ui_main window.h”
#包括
#包括
使用名称空间std::tr1;
#包括
#包括
#包括
#包括
#包括
#包括
主窗口::主窗口(QWidget*父窗口):
QMainWindow(父级),
用户界面(新用户界面::主窗口)
{
共享ptr主布局(新QHBoxLayout);
共享的ptr mainFeeds(新的QTreeView);
mainLayout->addWidget(mainFeeds.get());
共享的ptr mainWidget(新的QWidget);
mainWidget->setLayout(mainLayout.get());//addWidget(rightItems.get());
共享的\u ptr rightPreview(新的QListView);
rightLayout->addWidget(rightPreview.get());
rightWidget->setLayout(rightLayout.get());
mainLayout->addWidget(rightWidget.get());
此->setCentralWidget(mainWidget.get());
}
MainWindow::~MainWindow()
{
删除用户界面;
}
以及输出(我使用Qt Creator):

正在启动/path/myproject-build-desktop-Qt_4_8_2_in_path_local_Release/myproject。。。 程序意外地完成了。 /path/myproject-build-desktop-Qt_4_8_2_in_path_local_Release/myproject已退出,代码为0

当我注释标记行时,程序运行,但我有一个空窗口

我有两个问题:

  • 为什么这行会出错
  • <> LI>使用Qt?使用智能指针(实际上是构建健壮的C++代码)是正确的方法吗? 谢谢你的帮助, 提前
    谢谢。

    回答您的第二个问题,不,您尝试将共享PTR与Qt一起使用的方式不起作用

    您的共享指针在函数结束时超出范围(这会破坏指向的对象,因为它们是管理对象生命周期的唯一共享对象,因此也是最后一个共享对象),而Qt对象仍保留指向刚刚删除的对象的原始指针。因此,仅出于这个原因,当Qt试图处理无效对象时,您的代码将无法工作。这是未定义的行为


    此外,Qt还进行自己的资源管理。将指向子对象的原始指针传递给其父对象,当父对象超出范围时,父对象将负责删除子对象。因此,在这一点上,子对象的析构函数无论如何都会被调用。

    回答第二个问题,不,您尝试将共享ptr与Qt一起使用的方式不起作用

    您的共享指针在函数结束时超出范围(这会破坏指向的对象,因为它们是管理对象生命周期的唯一共享对象,因此也是最后一个共享对象),而Qt对象仍保留指向刚刚删除的对象的原始指针。因此,仅出于这个原因,当Qt试图处理无效对象时,您的代码将无法工作。这是未定义的行为


    此外,Qt还进行自己的资源管理。将指向子对象的原始指针传递给其父对象,当父对象超出范围时,父对象将负责删除子对象。因此,此时,子对象的析构函数仍被调用。

    Qt以自己的方式管理对象的生存期。当您使
    A
    成为
    B
    的子级时,则
    A
    将在
    B
    销毁时被
    delete
    'd

    那么在这一行呢,

    mainWidget->setLayout(mainLayout.get());
    
    您使
    mainLayout
    成为
    mainWidget
    的子级

    由于在
    mainLayout
    之后声明了
    mainWidget
    ,它将首先被删除。和
    mainloayout
    也将被删除。但是
    shared\u ptr
    将再次尝试删除
    mainLayout

    Qt
    中,您应该非常小心地使用智能指针。Qt内存管理通常拥有对象的所有权(但并不总是如此)。此外,您可能更喜欢使用本机
    Qt
    智能指针

    • 作为指向
      QObject
    • 作为std::unique\u ptr等的替代品
    • /对于切碎的指针

    Qt以自己的方式管理对象的生命周期。当您使
    A
    成为
    B
    的子级时,则
    A
    将在
    B
    销毁时被
    delete
    'd

    那么在这一行呢,

    mainWidget->setLayout(mainLayout.get());
    
    您使
    mainLayout
    成为
    mainWidget
    的子级

    由于在
    mainLayout
    之后声明了
    mainWidget
    ,它将首先被删除。和
    mainloayout
    也将被删除。但是
    shared\u ptr
    将再次尝试删除
    mainLayout

    Qt
    中,您应该非常小心地使用智能指针。Qt内存管理通常拥有对象的所有权(但并不总是如此)。此外,您可能更喜欢使用本机
    Qt
    智能指针

    • 作为指向
      QObject
    • 作为std::unique\u ptr等的替代品
    • /对于切碎的指针

    使用调试器将执行跟踪到错误发生的点。使用调试器将执行跟踪到错误发生的点。因此,如果我想把事情做好,我在处理Qt元素时必须不要使用智能指针?@GlinesMome,在处理Qt窗口小部件堆栈时,不应该使用所有者智能指针。因此,如果我想让事情变得更好,我必须在处理Qt元素时不要使用智能指针?@GlinesMome,在处理Qt组件堆栈时,你不应该使用所有者智能指针。