遇坑
今天在用QT的时候,传从主ui页面创建的一个指针到建模ui页面,在运行时程序发生奔溃。经过测试发现问题,主页面的指针和传进建模页面的指针不是同一个,导致在调用类指针方法时发生错误。
测试
以下代码仅展示测试代码的部分,不可运行。但能从下面代码可以说明主题的遇坑经过,以及解决问题方法,从而进行总结。
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "template_management.h"
#include "box_api.h"
#include <memory.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
// 主页面
Ui::MainWindow *ui;
// 模板管理
template_management *template_management_interface = new template_management(box_api_);
// 数据库、日志接口
BoxApi *box_api_ = new BoxApi;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDesktopWidget>
#include <QCompleter>
#include <QKeyEvent>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsItem>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
box_api_->init(); // 初始化数据和日志
std::cout << "box_api_1: " << box_api_ << std::endl; // 打印地址
}
MainWindow::~MainWindow()
{
delete ui;
delete template_management_interface; // 模板管理
}
template_management.h
#ifndef TEMPLATE_MANAGEMENT_H
#define TEMPLATE_MANAGEMENT_H
#include <QWidget>
#include "customsense.h"
#include <memory>
#include <QLabel>
#include <QDebug>
#include <QPushButton>
#include "enum_type.h"
#include "box_api.h"
namespace Ui {
class template_management;
}
class template_management : public QWidget
{
Q_OBJECT
public:
explicit template_management(BoxApi *box_api = nullptr, QWidget *parent = nullptr);
~template_management();
private:
Ui::template_management *ui;
BoxApi *box_api_;
};
#endif // TEMPLATE_MANAGEMENT_H
template_management.cpp
#include "template_management.h"
#include <QDesktopWidget>
#include "ui_template_management.h"
template_management::template_management(BoxApi *box_api, QWidget *parent) :
QWidget(parent), ui(new Ui::template_management), box_api_(box_api)
{
ui->setupUi(this);
std::cout << "box_api_2: " << box_api_ << std::endl; // 打印地址
}
template_management::~template_management()
{
delete ui;
}
程序运行结果:
box_api_2: 0x11b7a00
box_api_1: 0x30698840
由上可知,传递的地址不一样。故将mainwindow.h的内容进行更改,将成员变量BoxApi *box_api_ = new BoxApi; 放到创建建模页面之前。
更改后的mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "template_management.h"
#include "box_api.h"
#include <memory.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
// 主页面
Ui::MainWindow *ui;
// 数据库、日志接口
BoxApi *box_api_ = new BoxApi;
// 模板管理
template_management *template_management_interface = new template_management(box_api_);
};
#endif // MAINWINDOW_H
运行结果
box_api_2: 0x2b293020
box_api_1: 0x2b293020
这次两个地址一样了。
总结
由测试可知:创建一个类,首先类对成员变量进行空间分配(此时成员变量没有进行初始化)。然后成员变量按申明顺序进行初始化,值可以从直接赋值得到以及从初始化列表进行构造得到(成员变量的初始化顺序只取决于成员变量的声明顺序和列表的初始化顺序无关)。最后才执行构造函数的函数体。