Går det att lägga till ett argument i en konstruktör om den redan har färdiga argument? C++

Permalänk

Går det att lägga till ett argument i en konstruktör om den redan har färdiga argument? C++

Jag håller på med QT C++ och det är ett jävla bråk märker jag. Allt var så mycket enklare med C.
Men tids nog så ska jag lära mig det här också.

Jag har en klass som heter MainWindow.

QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); void dependency_injection(Database &database); private slots: void on_connect_sql_pushButton_clicked(); void on_disconnect_sql_pushButton_clicked(); private: Ui::MainWindow *ui; Database database; }; #endif // MAINWINDOW_H

Vid initialisering av klassen MainWindow så SKALL objektet database vara inkluderat. Detta måste ske via konstruktören MainWindow(QWidget *parent = nullptr); och inte vid den publika funktionen void dependency_injection(Database &database);

Men konstruktören MainWindow(QWidget *parent = nullptr); ser ut så här i verkligheten.

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

Och när jag skapar klassen så ser den ut så här.

#include "mainwindow.h" #include <QApplication> #include "database.h" int main(int argc, char *argv[]){ QApplication a(argc, argv); /* Create classes */ QSqlDatabase qSqlDatabase = QSqlDatabase::addDatabase("QMYSQL"); Database database(qSqlDatabase); /* Create the frames */ MainWindow w; // <- objektet database ska vara i konstruktören /* Inject dependencies here */ w.dependency_injection(database); // <- Så här ska det inte se ut /* Show main frame */ w.show(); return a.exec(); }

Men problemet är att om jag anropar konstruktören av MainWindow så kan jag inte använda argumenten QWidget *parent): QMainWindow(parent) , ui(new Ui::MainWindow)

Frågeställning:
Jag initialiserar ett objekt igenom

MainWindow w;

Konstruktören ser ut som detta. Jag vet vad det betyder. Om jag lämnar funktionens konstruktör med tomma argument, då skapar den ett standard argument, som är NULL.

MainWindow(QWidget *parent = nullptr);

Men....när konstruktören körs så används dessa argument.

(QWidget *parent): QMainWindow(parent) , ui(new Ui::MainWindow)

Vad betyder :? Varför så konstig konstruktör? Jag blir virrig när jag ser detta. new, ::, Ui, ui, osv

Vart kommer ui(new Ui::MainWindow) ifrån?
Om jag skulle vilja implementera database som argument för

MainWindow w(database)

Då blir det helt enkelt en ny konstruktör och därmed så körs INTE .

(QWidget *parent): QMainWindow(parent) , ui(new Ui::MainWindow)

Hur gör man här?

Jag kan inte anropa konstruktören så här

MainWindow w(database); <- Anrop MainWindow(Database &database, QWidget *parent = nullptr); <- Dekleration MainWindow::MainWindow(Database &database, (QWidget *parent): QMainWindow(parent) , ui(new Ui::MainWindow) <- Konstruktörens argument

Permalänk
Medlem

Du kan väl bara lägga till database som argument till konstruktorn för MainWindow? D.v.s.:

// database måste ligga före parent eftersom parent har ett default-argument. MainWindow(Database &database, QWidget *parent = nullptr); // Variablerna måste initialieras i samma ordning som de är deklarerade, d.v.s. ui före database MainWindow::MainWindow(Database &database, QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow), database(database) { ui->setupUi(this); }

Syntaxen för konstruktorn kan se lite underlig ut om man är van vid ett språk som Java, se t.ex. denna sida för hur initialiseringslistor fungerar i C++.

Permalänk
Skrivet av perost:

Du kan väl bara lägga till database som argument till konstruktorn för MainWindow? D.v.s.:

// database måste ligga före parent eftersom parent har ett default-argument. MainWindow(Database &database, QWidget *parent = nullptr); // Variablerna måste initialieras i samma ordning som de är deklarerade, d.v.s. ui före database MainWindow::MainWindow(Database &database, QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow), database(database) { ui->setupUi(this); }

Syntaxen för konstruktorn kan se lite underlig ut om man är van vid ett språk som Java, se t.ex. denna sida för hur initialiseringslistor fungerar i C++.

Okej. Är det så man ska göra.
Ska det inte vara?

(Database &database, QWidget *parent) : database(database), QMainWindow(parent) , ui(new Ui::MainWindow)

Varför just tre argument efter : ?

Permalänk
Medlem
Skrivet av heretic16:

Okej. Är det så man ska göra.
Ska det inte vara?

(Database &database, QWidget *parent) : database(database), QMainWindow(parent) , ui(new Ui::MainWindow)

Varför just tre argument efter : ?

Du kan tekniskt sett lista dem i vilken ordning du vill, men de kommer ändå initialiseras i en särskild ordning (först basklasserna, därefter variablerna i den ordning de är deklarerade i klassen). Så det är bäst att lista dem i ordningen de initialiseras för att se till att man inte försöker använda en variabel innan den initialiserats. Kompilatorn kommer troligtvis ge dig en varning om du listar dem i fel ordning.

Varför det är tre argument är för att du både vill anropa konstruktorn för basklassen QMainWindow samt initialisera både ui och database. Du måste inte lista alla basklasser och variabler i initialiseringslistan om du inte vill, då default-initialiseras de istället.

Permalänk
Skrivet av perost:

Du kan tekniskt sett lista dem i vilken ordning du vill, men de kommer ändå initialiseras i en särskild ordning (först basklasserna, därefter variablerna i den ordning de är deklarerade i klassen). Så det är bäst att lista dem i ordningen de initialiseras för att se till att man inte försöker använda en variabel innan den initialiserats. Kompilatorn kommer troligtvis ge dig en varning om du listar dem i fel ordning.

Varför det är tre argument är för att du både vill anropa konstruktorn för basklassen QMainWindow samt initialisera både ui och database. Du måste inte lista alla basklasser och variabler i initialiseringslistan om du inte vill, då default-initialiseras de istället.

Då förstår jag.
Denna video förklarade detta helt utmärkt.
https://www.youtube.com/watch?v=1nfuYMXjZsA&ab_channel=TheChe...

C++ är häftigt!