Проблема, с которой я столкнулся, обсуждалась несколько раз, но я до сих пор не понимаю, как решить возникшую проблему. Я много программировал на C ++, но из-за работы переключился на Java. Я возвращаюсь в C ++, и теперь у меня много проблем с управлением памятью / указателями / ссылками и т. Д. c. Эта проблема проистекает из этого.
Для контекста, это файлы для проекта Qt 5.14, над которым я работаю.
Проблема в том, что у меня есть переменная частного класса с именем loggerLevel
и метод, который создает ошибку ошибки сегментации - getLevel
, которая просто возвращает значение loggerLevel. предполагается для хранения в переменной - это перечисление с именем Level, которое определено в заголовке класса.
Я не знаю, связана ли проблема с моим отсутствием знания или если я неправильно понимаю что-то о том, как классы работают в C ++, или если это что-то совершенно другое. В любом случае, если кто-нибудь может мне помочь, это было бы здорово:)
--- Исходный код ниже ---
logger. cpp
#include "logger.h"
QString debugHTML = "<font color=\"gray\">";
QString infoHTML = "<font color=\"black\">";
QString warningHTML = "<font color=\"yellow\">";
QString errorHTML = "<font color=\"orange\">";
QString criticalHTML = "<font color=\"red\">";
QString endHTML = "</font><br>";
Logger::Logger(QObject *parent,
QString fileName,
QTextEdit *editor) : QObject(parent)
{
m_editor = editor;
m_showDate = true;
loggerLevel = Level::INFO;
if (!fileName.isEmpty()) {
file = new QFile;
file->setFileName(fileName);
file->open(QIODevice::Append | QIODevice::Text);
}
}
void Logger::write(const QString &value) {
QString text = value;
if (m_showDate) {
text = QDateTime::currentDateTime()
/*.toString("dd.MM.yyyy hh:mm:ss ") + text;*/
.toString("hh:mm:ss: ") + text;
}
QTextStream out(file);
out.setCodec("UTF-8");
if (file != 0) {
out << text;
} else {
//TODO: add QMessageBox here with error
}
//Adds HTML color/formatting
switch(loggerLevel)
{
case DEBUG: text = debugHTML + text; break;
case INFO: text = infoHTML + text; break;
case WARNING: text = warningHTML + text; break;
case ERROR: text = errorHTML + text; break;
case CRITICAL: text = criticalHTML + text; break;
default: text = infoHTML + text; break;
}
text = text + endHTML;
if (m_editor != 0) {
m_editor->insertHtml(text);
} else {
//TODO: add QMessageBox here with error
}
}
void Logger::write(const Level &level, const QString &value) {
Level prevLoggerLevel = Logger::getLevel();
Logger::setLevel(level);
write(value);
Logger::setLevel(prevLoggerLevel);
}
//--------Setters--------
void Logger::setLevel(const Level &level) {
loggerLevel = level;
}
void Logger::setShowDateTime(bool value) {
m_showDate = value;
}
//--------Getters--------
Logger::Level Logger::getLevel() {
return loggerLevel;
}
Logger::~Logger() {
if (file != 0) {
file->close();
}
}
logger.h
#ifndef LOGGER_H
#define LOGGER_H
#include <QObject>
#include <QPlainTextEdit>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
class Logger : public QObject
{
Q_OBJECT
public:
explicit Logger(QObject *parent,
QString fileName = 0,
QTextEdit *editor = 0);
~Logger();
void setShowDateTime(bool value);
enum Level
{
DEBUG,
INFO,
WARNING,
ERROR,
CRITICAL
};
private:
QFile *file;
QTextEdit *m_editor;
bool m_showDate;
Level loggerLevel;
signals:
public slots:
void write(const QString &value);
void write(const Level &level, const QString &value);
void setLevel(const Level &level);
Level getLevel();
};
#endif // LOGGER_H
MainWindow. cpp
#include <string>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "settingsdialog.h"
#include "logger.h"
Logger *logger;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QString logFileName = "log.txt";
Logger *logger = new Logger(this, logFileName, ui->loggerOutput);
logger->write(Logger::Level::INFO, "Logger Initilized!");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_toolButton_clicked()
{
SettingsDialog settingsDialog;
settingsDialog.setModal(true);
settingsDialog.exec();
}
//Left Side of controller
void MainWindow::on_s_leftJoystickX_Throttle_sliderMoved(int position)
{ ui->l_leftJoystickX->setText(QStringLiteral("X-Axis: %1%").arg(position)); }
void MainWindow::on_s_leftJoystickY_Throttle_sliderMoved(int position)
{ ui->l_leftJoystickY->setText(QStringLiteral("Y-Axis: %1%").arg(position)); }
void MainWindow::on_s_leftTrigger_Throttle_sliderMoved(int position)
{ ui->l_leftTrigger->setText(QStringLiteral("Trigger: %1%").arg(position)); }
void MainWindow::on_s_joystickThrottle_sliderMoved(int position)
{ ui->l_joystickThrottle->setText(QStringLiteral("Throttle: %1%").arg(position)); }
//Right Side of controller
void MainWindow::on_s_rightJoystickX_Throttle_sliderMoved(int position)
{ ui->l_rightJoystickX->setText(QStringLiteral("X-Axis: %1%").arg(position)); }
void MainWindow::on_s_rightJoystickY_Throttle_sliderMoved(int position)
{ ui->l_rightJoystickY->setText(QStringLiteral("Y-Axis: %1%").arg(position)); }
void MainWindow::on_s_rightTrigger_Throttle_sliderMoved(int position)
{ ui->l_rightTrigger->setText(QStringLiteral("Trigger: %1%").arg(position)); }
void MainWindow::on_s_keyboardThrottle_sliderMoved(int position)
{ ui->l_keyboardThrottle->setText(QStringLiteral("Throttle: %1%").arg(position)); }
void MainWindow::on_b_keyboardAction_1_clicked()
{
logger->write(Logger::Level::CRITICAL, "test");
}
Есть еще файлы, но я считаю, что они не имеют отношения к проблеме, при необходимости я могу опубликовать другие файлы также.
----- Решение! -----
@ churill Решение объясняет, что нужно сделать, чтобы решить эту проблему, но я также буду подробности ниже, чтобы завершить этот вопрос.
Поскольку я уже сделал предварительное объявление logger
Logger *logger
в верхней части MainWindow. cpp, создав новый объект Logger
Logger *logger = new Logger(this, logFileName, ui->loggerOutput);
не требуется, поэтому вызов имени переменной пересылки объявлений вместо создания нового объекта Logger
logger = new Logger(this, logFileName, ui->loggerOutput);
решает проблему!