c++构造函数

C++ constructor

本文关键字:构造函数 c++      更新时间:2023-10-16

我有一个MainWindow类

在类的一个方法中,我以

的方式调用另一个类("test")
 test = new Test (this,app_language,&filename2); 

测试类是:

Test::Test(QWidget *parent,QString lang, QString *filename)
: QDialog(parent)
, ui(new Ui::Report)
{
    ui->setupUi(this);
}

方法之一Test Class I以这种方式改变文件名的值

void Test::on_pushButton_clicked()
{
  filename = "TEST CLASS";
}

但是编译器返回错误,因为filename没有声明

我的问题是:

如何在测试类的方法中使用文件名并返回新值给主窗口类?

你应该在你的类中添加这样的成员:

class Test
{
// ...
    void setFilename( const QString& aFilename ) { m_Filename = aFilename; }
    QString filename() const { return m_Filename; }
private:
    QString m_Filename;
};

并且在所有函数中传递const QString&而不是QString*。在此之后,您的代码将编译:

void Test::on_pushButton_clicked()
{
    m_Filename = "TEST CLASS";
}

这个问题有两个答案。第一种方法很简单,可以直接快速地回答问题,但不建议使用。

我甚至不愿意向你展示第一个答案,因为它是糟糕的设计,可能会导致以后的问题,但我还是决定展示这个解决方案,因为它说明了变量作用域的概念,以及为什么你不能从一个函数访问通过另一个函数传入的数据。


你得到编译器错误的原因是因为函数参数只在它们定义的函数中有作用域。

这意味着,在Test的构造函数中,三个参数(QWidget *parent, QString langQString *filename)只能在构造函数体中访问。一旦程序控制退出构造函数,这些参数将被销毁,您就不能再访问它们的数据。

如果您希望访问其他函数中的数据,就像您在void Test::on_pushButton_clicked()中明确希望做的那样,您需要将值存储在数据成员中。

在你的代码中,parent的值被传递给QDialog的构造函数并存储在那里,所以你不必对它做任何特殊的处理,但是你没有存储langfilename的值,所以你失去了对它们的访问权。

要使您的代码与当前设计兼容,您需要进行以下修改:

class Test : public QDialog{
    // ...
private:
    QString language;
    QString *filename;
};
Test::Test(QWidget *parent, QString app_language, QString *f)
: QDialog(parent), language(app_language), filename(f), ui(new Ui::Report)
{
    ui->setupUi(this);
}
void Test::on_pushButton_clicked()
{
    *filename = "TEST CLASS";
}

第一个答案是一个非常糟糕的主意,因为你应该总是尽可能地保持你的代码松散耦合,而你解决问题的方式在你的MainWindow类和Test类之间创建了一个非常紧密的耦合。


第二个答案向您展示了一种更好的方法,可以通过类之间更松散的耦合来解决问题。事实上,Test类与以下代码中的MainWindow类完全没有知识或联系。

class Test : public QDialog{
    Q_OBJECT
public:
    Test(QWidget *parent, QString app_language);
    // ...
signals:
    void filenameChanged(QString const &newFilename);
    // ...
private:
    QString language;
};
Test::Test(QWidget *parent, QString app_language)
: QDialog(parent), language(app_language), ui(new Ui::Report)
{
    ui->setupUi(this);
}
void Test::on_pushButton_clicked()
{
    emit filenameChanged("TEST CLASS");
}
// MAIN WINDOW CLASS
class MainWindow : public QMainWindow{
    Q_OBJECT
public:
    // ...
    void showTestClass();
public slots:
    void filename2Changed(QString const &newFilename);
private:
    QString filename2;
    QString app_language;
};
void MainWindow::showTestClass()
{
    Test test(this, app_language);
    connect(&test, &Test::filenameChanged, this, &MainWindow::filename2Changed);
    test.exec();
}
void MainWindow::filename2Changed(QString const &newFilename)
{
    filename2 = newFilename;
}

信号槽机制是Qt的一个核心特性,也是设置消息耦合的一个方便的例子。