当我引用引用变量src_的属性时,我的程序终止。 代码的主要思想是MainWindow类调用SettingsWindow类来显示一些设置。还有两个额外的类负责保存的设置,即ConfigSource和ConfigUpdater。 src_被定义为ConfigUpdater中的引用变量。这是代码:
MainWindow中的:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ConfigSource cfg;
settings = new SettingsWindow(cfg,this);
settings->print_config(cfg.config());
...
SettingsWindow标题和来源:
#ifndef SETTINGSWINDOW_H
#define SETTINGSWINDOW_H
#include <QMainWindow>
#include <QModelIndex>
#include <QSignalMapper>
#include <QRadioButton>
#include <QSpinBox>
#include <QTimer>
#include "cameracommands.h"
struct Config
{
/* General Options */
QString general_key_lock;
QString general_back_light;
};
class ConfigSource
{
public:
ConfigSource() {
qDebug() << "inside configSource :))";
config_.general_aperture_control = "Reset";
config_.general_automatic_exposure = "Full Auto";
}
Config config() const {return config_;}
void setConfig(const Config& cfg) {config_ = cfg;}
// Config config_;
private:
Config config_;
};
class ConfigUpdater : public QObject
{
Q_OBJECT
public:
ConfigUpdater(ConfigSource& src) : src_(src) {}
public slots:
void apply () {src_.setConfig(tempConfig_);}
void cancel() {tempConfig_ = src_.config();}
public:
void updateGeneralBackLight(QString s) {tempConfig_.general_back_light = s; qDebug() << "BackLight updated :)";}
void updateGeneralKeyLock(QString s) {tempConfig_.general_key_lock = s; qDebug() << "KeyLock updated :)";}
Config tempConfig_;
ConfigSource& src_;
};
//----------------------------
namespace Ui {
class SettingsWindow;
}
class SettingsWindow : public QMainWindow
{
Q_OBJECT
public:
explicit SettingsWindow(ConfigSource &src, QWidget *parent = 0);
~SettingsWindow();
void print_config(Config cfg);
signals:
void clicked(const QString &text);
void sendToPLC(QByteArray );
public slots:
void updateGeneralBackLight();
void updateGeneralKeyLock();
private:
void set_mappings();
Ui::SettingsWindow *ui;
ConfigUpdater *config_updater;
};
#endif // SETTINGSWINDOW_H
设置源文件
SettingsWindow::SettingsWindow(ConfigSource &src, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::SettingsWindow)
{
/* initializations */
ui->setupUi(this);
config_updater = new ConfigUpdater(src);
这一部分非常关键,当我尝试从apply和cancel slot访问src_时,程序终止,例如:
void SettingsWindow::on_pushButton_3_clicked() //apply
{
qDebug() << "Apply Button";
print_config(config_updater->src_.config());
config_updater->apply();
print_config(config_updater->src_.config());
}
void SettingsWindow::print_config(Config config)
{
qDebug() << config.general_key_lock;
qDebug() << config.general_back_light;
}
void SettingsWindow::on_sendToMainButton_clicked() /* cancel */
{
print_config(config_updater->tempConfig_);
config_updater->cancel();
print_config(config_updater->tempConfig_);
print_config(config_updater->src_.config_);
}
但是,打印_tempconfig变量可以正常工作!为简单起见,我从头文件中删除了一些按钮插槽。
如果你告诉我如何解决这个错误,我会感谢你。)
答案 0 :(得分:2)
ConfigSource cfg;
是MainWindow
的构造函数的本地。
当负责调用发生崩溃的插槽的信号时,MainWindow
构造函数已经完成执行(即使MainWindow
实例仍然存在),因此引用不再有效。
答案 1 :(得分:1)
ConfigSource
对象在MainWindow
构造函数中创建为局部变量,因此它在构造函数的末尾被销毁,所有其他引用都变为无效。
您可以将其声明为MainWindow
的成员,以延长其生命周期。
答案 2 :(得分:1)
您遇到的问题与之前提出此问题的问题基本相同。
早期的ConfigSource是SettingsWindow构造函数的本地,因此它太早被破坏了。现在ConfigSource是MainWindow构造函数的本地,因此当MainWindow构造函数退出时它会被销毁,但现在还为时尚早! ConfigSource对象必须至少与SettingWindow对象一样长。一种方法是将ConfigSource对象放在SettingsWindow对象中,但我似乎记得你不想这样做。另一种方法是在main中声明ConfigSource对象(因此只要程序执行它就会存在),并通过对SettingWindow构造函数的引用将其传递下来。
只有您了解代码的结构,您才需要了解对象的生存时间,并记住ConfigSource对象必须至少与SettingWindow对象一样长。你真的需要直接理解这个想法,否则你会遇到很多这些问题。
答案 3 :(得分:0)
另外两个答案很好地解释了这一点(ConfigSource cfg;
是你的MainWindow构造函数的本地,因此在构造函数完成后内存会被回收。)
修复 - 使用堆分配(通过运算符new
)