c++ - 使用 QT 取消引用 std::unique_ptr 时出现问题(分段错误)
问题描述
(对不起我未来的错误,我是fr)
我正在创建一个程序来用 C++ 中的电话控制电脑(https://github.com/titicplusplus/PCPhone)
服务器部分运行良好,所以我想为用户添加图形界面,我决定使用 QT。
当我停止程序 QT 时,我有分段错误,这会停止服务器。
我运行图形界面的功能:
void start_g(int argc, char **argv)
{
QApplication app(argc,argv);
QFile File(":/stylesheet.qss");
File.open(QFile::ReadOnly);
QString StyleSheet = QLatin1String(File.readAll());
app.setStyleSheet(StyleSheet);
ui interface; //QWidget window
interface.start();
std::cout << "start gui" << std::endl;
interface.show();
app.exec(); //return 0
return;
}
我将代码封装在一个函数中,因为我想在一个线程中运行它,但现在在我的测试期间,我不这样做。
这是我的类 ui(用户界面)
class ui : public QWidget
{
public:
ui();
void start();
void change_file();
void change_port();
void freset();
void fapply();
~ui(); //Here is the problem
private:
openf f_open; //to open the extension s file
std::unique_ptr<QFormLayout> formLayout;
std::unique_ptr<QGroupBox> settings;
std::unique_ptr<QVBoxLayout> main_layout;
std::unique_ptr<QGridLayout> grid;
std::vector< std::vector< std::unique_ptr<QPushButton> > > tab2d;
std::unique_ptr<QGroupBox> all_button;
std::unique_ptr<QSpinBox> port_l;
std::unique_ptr<QPushButton> button_f;
std::unique_ptr<QPushButton> apply;
std::unique_ptr<QPushButton> reset;
std::unique_ptr<QLabel> text_f;
};
和重要的功能
ui::ui() {}
void ui::start()
{
grid = std::make_unique<QGridLayout>( this );
/** Code that you don't need, I guess **/
std::cout << "setting part" << std::endl;
all_button = std::make_unique<QGroupBox>("Slide");
all_button->setLayout(grid.get());
port_l =std::make_unique<QSpinBox>(this);
port_l->setMaximum(65535);
port_l->setValue( config_json["port"].get<int>() );
button_f = std::make_unique<QPushButton>("Open Image" ,this);
text_f = std::make_unique<QLabel>(QString::fromStdString(fs::absolute(config_json["image"].get<std::string>())), this);
apply = std::make_unique<QPushButton>(" Apply " ,this);
reset = std::make_unique<QPushButton>("Reset" ,this);
//connect(button_f.get(), &QPushButton::clicked, this, &ui::change_file);
connect(port_l.get(), QOverload<int>::of(&QSpinBox::valueChanged), this, &ui::change_port);
connect(apply.get(), &QPushButton::clicked, this, &ui::fapply);
connect(reset.get(), &QPushButton::clicked, this, &ui::freset);
//auto fileName = QFileDialog::getOpenFileName(&window, "Open Image", "/home/$USER", ("Image Files (*.png *.jpg *.bmp)"));
formLayout = std::make_unique<QFormLayout>();
formLayout->addRow("The port", port_l.get());
formLayout->addRow(text_f.get(), button_f.get()); //////////The problem is here
//formLayout->addRow(apply.get(), reset.get());
settings = std::make_unique<QGroupBox>("Settings");
settings->setLayout(formLayout.get());
main_layout = std::make_unique<QVBoxLayout>(this);
main_layout->addWidget(all_button.get());
main_layout->addWidget(settings.get());
}
所以我在谷歌上看到,问题出在指针上,它们破坏了,所以我试试这个
ui::~ui()
{
main_layout = nullptr;
settings = nullptr;
all_button = nullptr;
std::cout << "1u" << std::endl;
button_f = nullptr;
std::cout << "2u" << std::endl;
text_f = nullptr;
std::cout << "3u" << std::endl;
apply = nullptr;
std::cout << "4u" << std::endl;
reset = nullptr;
std::cout << "5u" << std::endl;
grid = nullptr;
std::cout << "bye bye" << std::endl;
}
结果是[错误是法语,所以我尝试翻译它]:
1u
Segmentation fault (core dumped)
当我删除这一行formLayout->addRow(text_f.get(), button_f.get());
text_f 和 button_f 的顺从没有问题,但是下一个(应用和重置)。
1u
2u
3u
Segmentation fault (core dumped)
在谷歌上,我看到很多时候人们使用指针而不是 std::unique_ptr 和 qt,但我通常看到人们说“智能指针比普通指针好。另外,我尝试替换 button_f.get()
为std::move(button_f).get()
但这不起作用。
有关信息,我使用的是 Ubuntu 20.04,带有 g++-9.3 和 qt5。预先感谢您的回答!
解决方案
感谢 GM 和 vahancho
我明白为什么我不需要这样做std::unique_ptr
。
当我学习 C++ 和指针时,有规则 : write one delete for every new
,或者更好的是,使用smart pointer
.
但是有了这两个主题:
https://codereview.stackexchange.com/questions/43189/deleting-pointers-in-qt5/43201
对于 QT 对象,是 QT 在删除类时删除指针。所以我只需要改变我所有的std::unique_ptr
原始指针。
推荐阅读
- kubernetes - Kubernetes Pod 跨节点通信,它是如何工作的?
- javascript - 如果这些不是表单的一部分但正在由 javascript 解析,浏览器是否会将键盘输入保存在输入标记中?
- javascript - Angular 6,从对象中获取新对象
- kiwi-tcms - 内部错误跟踪器:无法删除它
- java - Springboot 项目的 Tomcat 到 WebLogic Server 迁移期间的错误
- java - 初始化数组和构造函数不起作用
- c# - 在 C# 中按日期对文件夹进行排序
- jmeter - 为什么我仍然在 JMETER 中出现错误 403 响应代码?
- html - 烧瓶返回数据框表结果但无法在表中显示
- sql - 从 BigQuery 中的重复嵌套列中获取参数数组