对象在从函数返回时被销毁

object destroyed when return from the function

本文关键字:返回 函数 对象      更新时间:2023-10-16

我正在处理qt项目,注意到我的应用程序崩溃了
ON调试我发现这是因为qpushbutton对象没有被创建/初始化。

现在我不明白为什么它没有初始化?

我在命名空间中编写了一个函数,它调用所有Qbutton的构造函数,并且我通过引用该函数来传递对象那么,一旦函数返回,它是否应该保留其值?但在我的情况下,函数一返回就被破坏了?它是否与命名空间有关???

任何帮助或批评都会有帮助吗?

MY_Utility.h
class MY_Utility
{
private:
QPushButton* add_cal_button_; 
QPushButton*  sub_cal_button_; 
QPushButton*  mul_button_; 
}
My_Utility.cpp
namespace
{
void create_push_button_for_cal( QPushButton *button_cal, QString button_name, QGridLayout *grid, int grid_row, int grid_col )
{
button_cal = new QPushButton( button_name );
if(!button_cal )
{
msg.setInformativeText("The code does not come here so object is created");
QMessageBox msg;
msg.setText("Messsage");
msg.setInformativeText("OBject not initialised in create_push button  ");
msg.exec();;
}
button_cal->setFixedSize( 200 , 40 );
button_cal->setVisible( false );
grid->addWidget(  button_cal, grid_row, grid_col );
}

// function where we call all button created
void create_main_view( MY_Utility* main_p, QTreeWidget* tree_p, QTableWidget* table_p, QPushButton* add_cal_button_,  
                             QPushButton* sub_cal_cal_button_, 
                             QPushButton* mul_cal_button_,
{
QWidget*        center_p = new QWidget( main_p );
QHBoxLayout*    layout_p = new QHBoxLayout( center_p );
QGridLayout*    grid     = new QGridLayout( center_p );
grid->setSpacing( 1 );
create_push_button_for_cal( add_cal_button_, "addition_calculate" , grid, 1, 2 );
if( !add_cal_button_ )
{
QMessageBox msg;
msg.setText("Messsage");
msg.setInformativeText("OBject not initialised in first part of message  why not ?? ");
msg.exec();;
}
create_push_button_for_cal( sub_cal_cal_button_ ,"sub_Calculate",           grid, 2, 2 );
create_push_button_for_cal( mul_cal_button_ ,    "multplication_Calculate", grid, 3, 2 );
// Make the QWidget the central widget so we can resize within it
main_p->setCentralWidget( center_p );
bla .. 
bla ..

}
}
My_Utility::set_all_cal_button_visible(){
add_cal_button_->setVisible(true) ; // it crashes here 
}

您的问题是C++问题,而不是Qt问题。

void create_push_button_for_cal(QPushButton *button_cal, QString button_name)
{
button_cal = new QPushButton(button_name);
Q_ASSERT(button_cal);
}

指针(地址)通过值传递。您的代码会丢弃这个值,并用指向新实例的指针覆盖它。

对空button_cal的检查是无用的,因为new有一个很好的不变量:如果它后面的代码执行了,就意味着它成功地分配了内存。它让生活变得非常简单:如果new返回一个值,那就没问题。它不会返回无效或null值。

如果new失败,那么断言将永远不会执行,事实上,new甚至不会返回值。它会抛出一个异常,当抛出该异常时,你几乎无能为力,因为做任何事情都需要更多的内存,而我们刚刚用完了:(

您需要更改函数的签名,以返回指向新创建的实例的指针。您还应该通过const引用而不是通过值传递Qt类。如果函数中的其他代码可能引发异常,请使用智能指针来保护自己不泄露按钮实例。因此:

QPushButton * create_push_button_for_cal(const QString & button_name) {
QScopedPointer<QPushButton> btn(new QPushButton(button_name));
...
// If any code here throws an exception, the scoped pointer will delete
// the button instance, so that it won't leak.
...
return btn.take();
}