【日常遇坑总结】类成员变量的空间分配和初始化顺序

遇坑

今天在用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

这次两个地址一样了。

总结

由测试可知:创建一个类,首先类对成员变量进行空间分配(此时成员变量没有进行初始化)。然后成员变量按申明顺序进行初始化,值可以从直接赋值得到以及从初始化列表进行构造得到(成员变量的初始化顺序只取决于成员变量的声明顺序和列表的初始化顺序无关)。最后才执行构造函数的函数体。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值