MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
В этом разделе кода после : что делает
QMainWindow(parent),
ui(new Ui::MainWindow)
означает?
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
В этом разделе кода после : что делает
QMainWindow(parent),
ui(new Ui::MainWindow)
означает?
Это вопрос С++. То, что вы смотрите, называется списками инициализации. QMainWindow(parent) вызывает конструктор для MainWindow суперкласса (QMainWindow) и ui(new Ui::MainWindow) строит член ui.
В качестве дальнейшего объяснения обратите внимание, что класс, сгенерированный компилятором пользовательского интерфейса, также вызывается (в данном случае) MainWindow, но он принадлежит пространству имен Ui, поэтому его полное имя Ui::MainWindow. Это явно не то же самое, что класс MainWindow, который наследует от QMainWindow. Однако класс QMainWindow -derived имеет указатель-член (называемый Ui) на Ui::MainWindow, который инициализируется в конструкторе, как объяснялось выше. Посмотрите файл сгенерированный uic ui_mainwindow.h, чтобы увидеть, как все части совпадают. Также обратите внимание, что члены Ui::MainWindow являются общедоступными и поэтому полностью доступны в пределах MainWindow.
Альтернативный дизайн заключается в объединении идентичности двух классов MainWindow с использованием множественного наследования, получения собственного MainWindow из QMainWindow и Ui::MainWindow. Однако код, созданный текущей версией QtCreator, следует шаблону состава, а не шаблону наследования.
Эти две строки представляют собой так называемый список инициализации и выполняются во время создания каждого экземпляра этого класса. Каждый класс, наследующий другого, должен содержать вызов конструктора суперкласса в этом списке.
Вы также можете написать:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
ui = new Ui::MainWindow();
ui->setupUi(this);
}
который можно было бы найти более читаемым. Но использование списка инициализации немного быстрее и оптимизируется компилятором. Обратите внимание, что эти списки могут использоваться только в конструкторах, и вы не можете вызывать какие-либо функции объекта, потому что он еще не "живет". Но вы можете установить значение некоторых атрибутов и ссылаться на них в следующих операциях (например, чтобы избежать избыточности кода), например, в следующем примере:
#define DEFAULT_VALUE 1.0
class MyClass {
public:
MyClass() :
value1(DEFAULT_VALUE),
value2(value1)
{
}
MyClass(qreal value) :
value1(value),
value2(value1)
{
}
private:
qreal value1;
qreal value2;
};
Обратите внимание, что большинство компиляторов выдают вам предупреждение, если порядок членов в вашем списке инициализации не соответствует порядку в определении класса.