c++ - 在 qt 中调用构造函数外部的新运算符时崩溃

标签 c++ qt

我有一个关于在不同于构造函数的成员类上初始化指针时 qt 的奇怪(至少对我来说是意外的)行为(它崩溃)的问题。我附上我的部分代码:

在主窗口.h中:

class MainWindow : public QMainWindow
{
 ...
 private:
     QPixmap *qpm_s1_yaw;
     QPainter *s1_yaw_painter;
     ...
}

在 mainwindow.cpp 中:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
 ...
 initGraph(qpm_s1_yaw, s1_yaw_painter, ui->YAW1);
 ...
}

void MainWindow::initGraph(QPixmap *map, QPainter *painter, QLabel *label)
{
map = new QPixmap(label->size());
map->fill(Qt::white);
painter = new QPainter(map);

... doing some stuff ...

label->setPixmap(*map); // ++(Remember this LINE)++
}

这确实有效,但是当我评论该行时:

label->setPixmap(*map)

而是在构造函数 (MainWindow::MainWindow) 中设置 Pixmap,方法是:

ui->YAW1->setPixmap(*qpm_s1_yaw)

我遇到了段错误。

有人能解释一下它有什么问题吗?为了让它工作,我必须初始化构造函数中的所有指针(并在类成员 initGraph 中注释这些行),如下所示:

qpm_s1_yaw = new QPixmap(ui->YAW1->size());
s1_yaw_painter = new QPainter(qpm_s1_yaw);
initGraph(qpm_s1_yaw, s1_yaw_painter, ui->YAW1);
ui->YAW1->setPixmap(*qpm_s1_yaw);

谢谢

最佳答案

这是对 C++ 工作原理的一个微不足道的误解,与 Qt 无关。

您的代码对您说谎:您同样可以编写:initGraph(0, 0, ui->YAW1)。您正在初始化局部变量而不是类成员。您作为前两个参数传递的值不用于任何用途。

也完全没有必要用指针来持有像素图和画家。按值保存像素图,只在绘画时为其实例化一个画家。

当您不在像素图上绘画时让画家拿着像素图可能会导致在像素图被消耗(读取)时制作不必要的像素图拷贝:具有活跃画家的像素图被认为是“脏的”。

然后你应该做的是按值保存像素图,你可以从 initGraph 返回新值 - 这将 initGraph 与周围类的细节分离,其中像素图被存储。 initGraph 的用户可以选择不存储像素图,例如查询标签本身。

class MainWindow : public QMainWindow
{
  Ui::MainWindow ui; // hold by value
  ...
  QPixmap qpm_s1_yaw; // hold by value
  QPixmap initGraph(QLabel *label) {
    QPixmap pixmap{label->size()};
    pixmap.fill(Qt::white);
    QPainter painter{&pixmap};
    //... doing some stuff ...
    label->setPixmap(pixmap);
    return pixmap;
  }
public:
  explicit MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
    ui.setupUi(this);
    gpm_s1_yaw = initGraph(ui.YAW1);
  }
};

关于c++ - 在 qt 中调用构造函数外部的新运算符时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40755179/

相关文章:

c++ - 无法将参数 1 从 'char' 转换为 'const std::basic_string<_Elem,_Traits,_Ax> &'

c++ - 使用迭代器将部分文件流读入字符串

qt - 我应该多久在 QT 中设置一次数据库?

qt - 如何删除QTreeView缩进

css - 使用 "Less"或类似的东西生成 Qt 样式表

c++ - std:map 与 operator= 不匹配

C++ 多个 C++ 文件 - ld : symbol(s) not found for architecture x86_64

c++ - 从随机数组输出最大最小值和平均值?

c++ - 导入QtQuick.Window 2.2 QML模块未找到

c++ - Qt:从一个对象发出相同的信号,但参数不同;插槽根据接收到的参数进行区分