如何在不同的类中使用 QNetworkAccessManager?类之间一般共享重要数据?
Posted
技术标签:
【中文标题】如何在不同的类中使用 QNetworkAccessManager?类之间一般共享重要数据?【英文标题】:How to use QNetworkAccessManager in different classes? General sharing of important data between classes? 【发布时间】:2012-07-03 15:01:34 【问题描述】:我正在开发一个 MainWindow 应用程序来学习 C++ 和 Qt(C++ 和 QT 4.8)。 我想在我的应用程序的不同对象中执行 HTTP 请求,例如对话框/向导和 MainWindow。我知道我基本上应该每个应用程序有一个 QNetworkAccessManager。我的问题是,在课程之间传递这个 QNAM 的正确方法是什么?
目前我将它作为指针传递给我的向导的构造函数,但这似乎......不优雅且不灵活。让我的对话框或我决定制作的任何其他类访问我的 QNetworkAccessManager 的正确方法是什么?我想我对我需要让所有东西访问的任何数据都有同样的问题。
这里正确的 C++ 设计解决方案是什么?单例模式似乎是一种选择,但据我所知,这是一种糟糕的选择。我这里有一些代码来说明我的问题。
我的 MainWindow 构造函数和启动我的向导的插槽:
MyMainWindow::MyMainWindow
qnam = new QNetworkAccessManager();
...
MyMainWindow::wizardStarter
mywizard = MyWizard(vari, qnam, this);
我的向导构造函数,我在其中发出网络请求并在从用户那里获取数据后解析数据,因此我需要一个 QNetworkAccessManager:
MyWizard::MyWizard(SomeOtherArgument *vari, QNetworkAccessManager *qnam, QObject *parent)
...
this->ourQnam = qnam;
...
MyWizard::launchRequest(QUrl newUrl)
ourQnam->get(QNetworkRequest(newUrl));
【问题讨论】:
我推荐单例设计模式。为什么你认为这种模式不好? @hamed,如果你不使用正确的依赖注入,单例会隐藏类之间的依赖关系。单例设计模式没有错,只需使用适当的注入来传达您的类依赖于您的单例。 在单例的情况下如何添加适当的注入? @MJBoa,此示例使用构造函数注入,您可以使用另一种形式: MyClass* myClass = new MyClass( MySingleton::getInstance() );这仍然表明“MyClass”依赖于“MySingleton”,同时允许使用单例。它还允许您在测试的情况下轻松换出使用哪个单例。见Why Singletons Are Controversial 【参考方案1】:从您的问题来看,我认为您实际上是在问要使用哪种形式的 dependency injection(即将您的依赖 QNetworkAccessManager 注入到对象中)。
在您的情况下,您使用的是 构造函数注入。这是一种众所周知和公认的注射形式。它强烈地传达您的向导类取决于 QNetworkAccessManager,它使您的代码易于人们理解。如果您要使用单例从向导类实现中简单地获取静态 QNetworkAccessManager,虽然它具有删除构造函数注入的好处,但它隐藏了您的向导类使用 QNetworkAccessManager。
另一种众所周知的注入形式是Setter Injection,即setDelegate( delegate )
从专业上讲,您当前的方法没有任何问题,因为它再次清楚地传达了您的向导类取决于 QNetworkAccessManager 对象。
如果您有兴趣了解有关依赖注入的更多信息,可以阅读这里。
Dependency Injection
Dependency Injection in C++
【讨论】:
【参考方案2】:另一种方式见this帖子:
管理此类全局应用程序绑定对象的规范方法是将它们作为自动变量保存在
main
中,并使用辅助函数来访问它们。QPointer
自动跟踪对象的生命周期,因此永远不会悬空。
因此:
main.h - 界面
QNetworkAccessManager *nMgr();
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;
...
【讨论】:
以上是关于如何在不同的类中使用 QNetworkAccessManager?类之间一般共享重要数据?的主要内容,如果未能解决你的问题,请参考以下文章