简体   繁体   English

如何在不同的类中使用QNetworkAccessManager?课程之间的重要数据的一般共享?

[英]How to use QNetworkAccessManager in different classes? General sharing of important data between classes?

I have a MainWindow application I'm working on to learn C++ and Qt (C++ and QT 4.8). 我有一个MainWindow应用程序,我正在努力学习C ++和Qt(C ++和QT 4.8)。 I want to do HTTP requests in different objects of my application, such as Dialogs/Wizard and in the MainWindow. 我想在我的应用程序的不同对象中执行HTTP请求,例如Dialogs / Wizard和MainWindow。 I know I'm basically supposed to have one QNetworkAccessManager per application. 我知道我基本上应该为每个应用程序配备一个QNetworkAccessManager。 My question is, what is the proper way to pass this QNAM around between classes? 我的问题是,在课间通过这个QNAM的正确方法是什么?

At the moment I have it as a pointer I pass to the constructor of my wizard but this seems... inelegant and inflexible. 目前我将它作为指针传递给我的向导的构造函数,但这似乎......不优雅且不灵活。 What is the proper way to give my Dialogs or whatever other classes I decide to make, access to my one QNetworkAccessManager? 给我的Dialogs或我决定做的其他任何类的正确方法是什么,访问我的一个QNetworkAccessManager? I guess I have the same question about any piece of data I need to give everything access to. 我想我对提供所有访问权限所需的任何数据都有同样的问题。

What is the properly C++-designed solution here? 什么是正确的C ++设计解决方案? The singleton pattern seems like an option, but a bad one as I understand. 单身模式似乎是一种选择,但据我所知,这是一个糟糕的模式。 I have a bit of code here to show my question. 我在这里有一些代码来展示我的问题。

My MainWindow constructor and slot which launch my wizard: 我的MainWindow构造函数和插槽启动我的向导:

MyMainWindow::MyMainWindow
{
    qnam = new QNetworkAccessManager();
}

...

MyMainWindow::wizardStarter
{
    mywizard = MyWizard(vari, qnam, this);
}

My Wizard Constructor in which I'm making network requests and parsing data after getting data from the user, and therefore in which I need a QNetworkAccessManager: 我的向导构造函数,我在从用户获取数据后进行网络请求和解析数据,因此我需要一个QNetworkAccessManager:

MyWizard::MyWizard(SomeOtherArgument *vari, QNetworkAccessManager *qnam, QObject *parent)
{
    ...
    this->ourQnam = qnam;
    ...
}

MyWizard::launchRequest(QUrl newUrl)
{
    ourQnam->get(QNetworkRequest(newUrl));
}

From your question, I think you're really asking which form of dependency injection (ie injecting your dependent QNetworkAccessManager into objects) to use. 从您的问题来看,我认为您确实在询问使用哪种形式的依赖注入 (即将依赖的QNetworkAccessManager注入对象)。

In your case you're using Constructor injection . 在您的情况下,您正在使用构造函数注入 This is a perfectly known and accepted form of injection. 这是一种完全已知和可接受的注射形式。 It strongly communicates your wizard class depends upon the QNetworkAccessManager which makes your code easy for people to understand. 它强烈地传达您的向导类取决于 QNetworkAccessManager,它使您的代码易于人们理解。 If you were to use a singleton to simply grab a static QNetworkAccessManager from inside the wizard class implementation, while it has the benefit of removing the constructor injection, it hides that your wizard class uses the QNetworkAccessManager. 如果你使用单例来简单地从向导类实现中获取静态QNetworkAccessManager,虽然它具有删除构造函数注入的好处,但它隐藏了你的向导类使用QNetworkAccessManager。

Another well known form of injection is Setter Injection ie setDelegate( delegate ) 另一种众所周知的注射形式是Setter Injection,setDelegate( delegate )

Professionally speaking there is nothing wrong with your current approach as again it clearly communicates your wizard class depends upon the QNetworkAccessManager object. 从专业角度讲,您当前的方法没有任何问题,因为它清楚地表明您的向导类依赖于 QNetworkAccessManager对象。

Here is a bit of reading if you if you're interested in learning more about dependency injection. 如果您有兴趣了解有关依赖注入的更多信息,请阅读以下内容。

Dependency Injection 依赖注入

Dependency Injection in C++ C ++中的依赖注入

Another way is shown in this post: 另一种方式显示在这篇文章中:

The canonical way to manage such global application-tied objects is to keep them as automatic variables in main and use helper functions to access them. 管理这种全局应用程序绑定对象的规范方法是将它们作为自动变量保存在main并使用辅助函数来访问它们。 The QPointer automatically tracks the lifetime of the object, and thus won't ever be dangling. QPointer自动跟踪对象的生命周期,因此永远不会悬空。

Thus: 从而:

main.h - interface main.h - 接口

QNetworkAccessManager *nMgr();

main.cpp - implementation main.cpp - 实现

// This pointer is local to the translation unit, and is an
// implementation detail. It's not used anywhere else.
static QPointer<QNetworkAccessManager> globalManager;

// The global accessor method
QNetworkAccessManager *nMgr() {
  Q_ASSERT(!qApp || QThread::currentThread() == qApp->thread());
  return globalManager;
}

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);
  QNetworkAccessManager mgr;
  globalManager = &mgr;
  ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM