如何从 Qt/C++ 的子函数中调用非静态父函数?

Posted

技术标签:

【中文标题】如何从 Qt/C++ 的子函数中调用非静态父函数?【英文标题】:How to call to non-static parent function from within child function in Qt/C++? 【发布时间】:2016-04-20 18:10:08 【问题描述】:

我很难理解如何将父对象传递给子对象。 在 Qt 中,我有一个 MainWindow 类和一个 DoSomething() 函数。然后我在 MainWindow 中创建了一个 Job 对象,并尝试在 Job 的 DoItNow() 函数中调用 DoSomething。但我就是不知道该怎么做。

MainWindow.h

class Job;
class MainWindow : public QMainWindow

  Q_OBJECT

  public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    int value;
    void DoSomething();

  private:
  Job *job;

MainWindow.cpp

#include "mainwindow.h"
#include "job.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
ui(new Ui::MainWindow)

    ui->setupUi(this);
    job = new Job(this);   // passing this pointer to child


void MainWindow::DoSomething()   // do something 

工作.h

class Job : public QObject

  Q_OBJECT

  private:
    void DoItNow();

  public:
    explicit CDMcommand(QObject *parent = 0);

Job.cpp

#include "job.h"
#include "mainwindow.h"

Job::Job(QObject *parent) : QObject(parent)

  // some setups
  parent->value = 0;    // this is not working


void Job::DoItNow()

  parent->DoSomething();  // What is the pointer to MainWindow instance?

如何访问 *parent 中的非静态公共寄存器?

如何将 *parent 传递给作业实例中的函数?

【问题讨论】:

Qt 中,您通常使用信号和插槽来执行此操作。 c# 跟这个问题有什么关系? QObject 没有名为“value”的公共字段,也没有名为“DoSomething”的方法。这些是您在 MainWindow 类中定义的内容。要访问它们,必须将“父级”声明为 MainWindow 的实例,而不是 QObject。 也许我应该重新表述我的问题。我想在 MainWindow 中创建一个对象 Job 并且通过 Job 的一个函数来调用 MainWindow 的函数。这样做的正确方法是什么? 【参考方案1】:

也许我误解了这个问题,但我认为您对继承有点困惑。您的JobQObject 的子类,MainWindow 也间接继承自QObject,但MainWindowJob 之间没有直接关系。我对Qts的信号槽机制不是很熟悉,这里大概是走的路,但也许我可以为你提供一个不同的解决方案:

Job::Job(QObject *parent) : QObject(parent)

  // some setups
  parent->value = 0;    // this is not working

这不起作用,因为QObject 没有名为value 的成员。如果您可以使用 Jobs 构造函数而不以 QObject* 作为参数,那么只需声明一个

MainWindow* parentWindow;

作为Job 中的私有成员并将构造函数更改为

Job::Job(MainWindow *parentWindow) : QObject(parentWindow)

  // some setups
  parentWindow->value = 0;    // this will work now

然后也

void Job::DoItNow()

  parentWindow->DoSomething();  

可以正常工作。

【讨论】:

那是全局变量方式? parentWindow 在一个块中是一个参数,在另一个块中是一个全局变量。没有办法通过严格的代码审查。 @AlexanderVX 没有全局变量。如果你仔细阅读,我建议在Job 类中声明parentWindow inside。但是我会编辑以消除任何歧义【参考方案2】:

如何从“子”调用 Qt“父”对象方法 对象方法?

安全又简单的方法:

void Job::DoItNow()

   // first evaluate the pointer: is that of type we expect?
   MainWindow* pMainWindow = qobject_cast<MainWindow*>(parent());
   if (pMainWindow)
       pMainWindow->DoSomething();  // MainWindow::DoSomething must be exposed to class Job

当然,让两个类相互依赖太多是违反 OOP 原则的:这两个对象现在变得紧密耦合。在 cmets 中已经有一个很好的建议:为此使用显式的信号槽机制或提供接口以在解耦对象之间进行交互。

【讨论】:

也许我应该重新提出我的问题。我想在 MainWindow 中创建一个对象 Job 并且通过 Job 的一个函数来调用 MainWindow 的函数。这样做的正确方法是什么? 我发布的那个。但仍然考虑信号槽。我们两者都做。我们做我懒惰时发布的那个。

以上是关于如何从 Qt/C++ 的子函数中调用非静态父函数?的主要内容,如果未能解决你的问题,请参考以下文章

从嵌套类的函数访问父级的非静态成员

如何在 KeyDown 事件的子组件中调用父组件中定义的函数?

如何从 Flutter 中的子小部件调用父小部件功能

从静态函数调用非静态变量

java中成员变量代码块构造函数运行顺序

C++ 非静态成员函数的非法调用