1

tr1shared_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;
}

そして出力(私は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 で終了しました

マークされた行にコメントを付けると、プログラムは実行されますが、空のウィンドウが表示されます。

2 つの質問があります。

  1. この行がエラーになるのはなぜですか?
  2. Qt でスマート ポインターを使用する (実際には堅牢な C++ コードをビルドする) のは正しい方法ですか?

よろしくお願いします。

4

2 に答える 2

1

2 番目の質問に答えるには、いいえ、Qt で shared_ptrs を使用しようとしている方法が機能しません。

共有ポインターは、関数の最後でスコープ外になります (オブジェクトの有効期間を管理する唯一の、したがって最後の shared_ptr であるため、ポイント先のオブジェクトを破棄します)。Qt オブジェクトは、オブジェクトへの生のポインターをまだ保持しています。削除されたばかりです。そのため、Qt が無効なオブジェクトを処理しようとするため、コードは機能しません。それは未定義の動作です。

また、Qt は独自のリソース管理を行います。子オブジェクトへの生のポインターをその親に渡すと、親がスコープ外になったときに親が子を削除します。したがって、この時点で、とにかく子オブジェクトのデストラクタが呼び出されています。

于 2012-08-14T20:23:57.747 に答える
0

Qtは、独自の方法でオブジェクトの存続期間を管理します。Aの子を作成するとB、破棄されたときに'dにAなります。deleteB

だから、この行で

mainWidget->setLayout(mainLayout.get());

mainLayoutあなたはの子を作りますmainWidget

mainWidget後に宣言されているようmainLayoutに、最初に削除されます。そして、またmainLayout削除されます。しかし、その後、再度shared_ptr削除しようとmainLayoutします。

ここではQt、スマートポインタの使用に非常に注意する必要があります。Qt memeory管理は、多くの場合、オブジェクトの所有権を取得します(常にではありません)。また、ネイティブのQtスマートポインタを使用することをお勧めします

于 2012-08-14T20:33:57.297 に答える