Wpis z mikrobloga

Zetknąłem się z ciekawym problemem. Otóż QString potrafi wywalić program, kiedy nie ma deklaracji zmiennej w pliku nagłówkowym. Co ciekawe przy std::string problem nie występuje. Więc jeśli wam wali segfaulta dodajcie deklarację do nagłówkowego lub zmieńcie na string. Kompilator nie ma zastrzeżeń, ale program idzie w krzaki.

#programowanie #qt #c++
  • 17
@vipe: przetestowałem wszystko. Banalny kod

myclass.cpp

#include "myclass.h"
#include
#include

QString dowolny;
std::string dowolnystring;

//mystruct mydata;

myclass::myclass(QObject *parent) : QObject(parent)
{
dowolny = "cokolwiek";
dowolnystring = "string";
}

myclass.h

#ifndef MYCLASSH
#define MYCLASS
H

#include

class myclass : public QObject
{
Q_OBJECT
public:
explicit myclass(QObject *parent = nullptr);

private:

signals:

};

#endif // MYCLASS_H

W Qt Creator.

Kompiluje się, ale wywala.
21:35:21: The program has unexpectedly finished.
21:35:21: Wymuszono zakończenie
@Rasteris: przypadek.

a jak tworzysz zmienną globalną w headerze, to tak naprawdę tworzysz N inicjalizacji tych zmiennych globalnych w każdym .cpp gdzie ten header "dotrze"(nawet przez inne headery) i linker przypadkowo akurat wybiera taką kolejność inicjalizacji, że to działa. ale na innym kompilatorze/linkerze/komputerze może to się inaczej wybrać
@Rasteris: Weź to jakoś odizoluj tak, by się dało to zreprodukować, bo na tą chwilę bym powiedział że "I cannot reproduce the issue"/"u mnie działa".
Daj minimalną implementację MainWindow (czy też QMainWindow), która reprodukuje problem.
Inaczej to sobie możemy zgadywać.
@MamCieNaHita: właśnie czytam o tym problemie z kolejnością inicjalizacji i obejścia są mało ciekawe. Tworzę kilka obiektów na całe życie programu. W mainwindow pozostaje tylko w zasadzie inicjalizacja obiektów, obsługa przycisków i wyświetlania. Cała logika w klasach. Gdzieś te obiekty muszę utworzyć.
@deekox:

całe mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "myclass.h"

myclass mojaklasa;

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);

}

MainWindow::~MainWindow()
{
delete ui;
}

mainwindow.h
#ifndef MAINWINDOWH
#define MAINWINDOW
H

#include

QTBEGINNAMESPACE
namespace Ui { class MainWindow; }
QTENDNAMESPACE

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();

private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

Najprostszy z generacji w Qt
@Rasteris: Kilka podstawowych kwestii, które powinieneś zrozumieć:

1) Plik nagłówkowy i plik modułu (cpp) to z perspektywy kompilatora jedno i to samo. Ten podział jest dla nas - ludzi, aby łatwiej sobie kod organizować.

2) Kompilator, gdy kompiluje plik mainwindow.cpp, to tak na prawdę idzie linia po linii i jak znajdzie #include to w tym miejscu wstawi zawartość pliku include'owanego i skompiluje jak każdy inny kod. Zamiast #include mógłbyś równie dobrze