Сбой программы QT при использовании ключевого слова extern

#c #qt #qt5

Вопрос:

Я пытаюсь использовать глобальный объект для разных классов, используя ключевое слово extern, но это почему-то не работает в QT.

В принципе, я хотел создать общий объект GraphicsScene для рисования прямоугольников в одной и той же сцене, но в разных классах. Вот почему я подумал, что глобальный объект «scene_» был бы здесь хорошим выбором.

manwindow.cpp :

 QGraphicsScene *scene_ = new QGraphicsScene();  MainWindow::MainWindow(QWidget *parent)  : QMainWindow(parent)  , ui(new Ui::MainWindow) {  ui-gt;setupUi(this);  scene_-gt;setSceneRect(-300,-300,600,600);  ui-gt;graphicsView-gt;setScene(scene_);   QGraphicsRectItem *rectItem = new QGraphicsRectItem();  rectItem-gt;setRect(0,0,200,200);   scene_-gt;addItem(rectItem); }   MainWindow::~MainWindow() {  delete ui; }  

главное окно.h:

 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include lt;QGraphicsScenegt;  #include lt;QMainWindowgt;  extern QGraphicsScene *scene_;  QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE   class MainWindow : public QMainWindow  {  Q_OBJECT    public:  MainWindow(QWidget *parent = nullptr);  ~MainWindow();    private:  Ui::MainWindow *ui;  };  #endif // MAINWINDOW_H   

Здесь я хотел получить тот же указатель на объект _scene из главного окна.h и добавьте к нему второй прямоугольник.

A. c :

 #include "a.h"  #include "mainwindow.h"  #include lt;QGraphicsRectItemgt;    A::A()  {  QGraphicsRectItem *rectItem2 = new QGraphicsRectItem();  rectItem2-gt;setRect(0,0,200,200);  scene_-gt;addItem(rectItem2);  }  

main.cpp :

 #include "mainwindow.h"  #include lt;QApplicationgt;  int main(int argc, char *argv[]) {  QApplication a(argc, argv);  MainWindow w;  w.show();  return a.exec(); }  

Программа сразу же выходит из строя при ее запуске. (Из — за реализации ключевого слова)

 10:17:26: The program has unexpectedly finished. 10:17:26: The process was ended forcefully. Desktop_Qt_6_2_1_MinGW_64_bit-Debugdebugtest.exe crashed.  

Как мне исправить эту проблему или есть другой способ реализовать это?

Комментарии:

1. Он еще не был создан. Лучше было бы передать его, например, в конструкторе A. Но если вы хотите это исправить, вы можете сделать: если (!scene_) scene_ = новый QGraphicsScene(); и QGraphicsScene *scene_ = nullptr; в mainwindow.cpp

2. Это крайне плохой дизайн. Не делай этого. Будьте откровенны в отношении зависимостей ваших классов и объектов. Ошибка, которую вы видите, является только следствием этой плохой конструкции.

3. Я тоже так думал, но я каким-то образом заблокирован и не знаю, как его перепроектировать. Есть ли способ, который позволяет мне изменять ту же сцену, созданную в классе mainwindow, и может изменять ту же сцену в других классах без использования глобального указателя.

4. Передайте указатель от MainWindow этого к другим классам.

Ответ №1:

Для вашего дизайна будет работать синглтон, содержащий общие ресурсы (т. е. сцену).

Лучшая идея-объявить сцену частным членом MainWindow с помощью getter или еще лучше предоставить addItem() в качестве публичной функции:

 void MainWindow::addItem(QGraphicsItem *item) {  scene-gt;addItem(item); }