如何从另一个函数中访问一个功能,从C 中的第三个访问
How to access stuff in one function from another, called from third in c++
我有此代码:
void Forms::login() {
LoginForm *loginForm = new LoginForm;
loginForm->show();
}
void Forms::startGame() {
WorldForm *worldForm = new WorldForm;
worldForm->show();
loginForm->hide();
}
因此,我试图将所有逻辑与一个单独的文件联系起来,例如logics.cpp。首先,我仅使用常规功能,但是我无法从StartGame访问登录名(因为我不能简单地将其添加到.h文件中,这会崩溃所有程序,不要问为什么 - QT QUTER。这些类型是qwidgets)。现在我需要的是:
如何添加WorldForm&登录到类表单的根(或标题文件)的根,我不能这样做。
最终目标是调用startGame()(在这种情况下,是另一个文件中的另一个类的forms :: startGame()为静态函数),而startGame()应该能够隐藏登录名,如上所示。
我甚至不能这样做:
void Forms::world(int a) {
WorldForm *worldForm = new WorldForm;
if(a==0) {
worldForm->show();
}else{
worldForm->hide();
}
}
因为我需要worldForm
仅创建一次,这将为每个呼叫创建很多实例1。
这是我的代码:https://github.com/ewancoder/game
您正在寻找的是成员变量,而单身模式则以QApplication
的样式完成。
您似乎正在做的是声明一个小部件类型的全局变量:
// interface (.h)
extern QWidget myWidget;
// implementation (.cpp)
QWidget myWidget;
这将从不工作,因为在main()
启动之前发生了这样的对象的构建!这是您在Delphi和C 之间所拥有的关键差异。在Delphi中,您必须自己调用对象的构造函数。在C 中,它是自动完成的 - 对于全局变量,所有内容都是由main()
执行时构建的。您需要使用指针。
可以声明和实现Forms
类,如下所示。
类是不可复制的,因为QScopedPointer
不可复制,因此我们应该向人类读者明确。无论如何,这堂课都没有充分的理由可以复制,即使我们使用了QSharedPointer
。
使用QScopedPointer
智能指针,以使表格不会泄漏。QScopedPointer
的破坏者会自动释放分配的形式(如果有)。它可以用作布尔,当它是非效果时是真的。
班级强制执行一个不变的,即它的实例。该实例应在QApplication
之后的main()
函数中构造。您可以使用静态Forms::instance()
方法从任何地方访问此实例。
例如,在LoginForm::on_loadButton_clicked()
中,您将使用
Forms::instance()->world();
// core.h - interface
#include <QScopedPointer>
class LoginForm;
class WorldForm;
class Forms {
Q_DISABLE_COPY(Forms)
QScopedPointer<LoginForm> m_loginForm;
QScopedPointer<WorldForm> m_worldForm;
static Forms * m_instance; // declaration
public:
Forms();
~Forms();
static Forms * instance();
void login(int act = 0);
void world();
};
// forms.cpp - implementation
#include "core.h"
#include "Forms/loginform.h"
#include "Forms/worldform.h"
Forms * Forms::m_instance = 0; // definition
// The runtime default-constructs static class members, so technically
// the explicit initialization to a null pointer is not necessary.
void Forms::login(int act) {
if (!m_loginForm) m_loginForm.reset(new LoginForm);
switch(act) {
case 1:
m_loginForm->hide();
break;
default:
m_loginForm->show();
}
}
void Forms::world() {
if (!m_worldForm) m_worldForm.reset(new WorldForm);
m_worldForm->show();
}
Forms::Forms() {
Q_ASSERT(! m_instance);
m_instance = this;
}
Forms::~Forms() {
m_instance = 0;
}
Forms * Forms::instance() {
return m_instance;
}
// main.cpp
#include <QApplication>
#include "Classes/core.h"
int main(int argc, char *argv[]) {
QApplication game(argc, argv);
Forms forms;
forms.login();
return game.exec();
// The local object instances are destructed in C++-generated-code.
// The order of destruction is opposite to the order of definition.
// The compiler puts the following code "here":
// forms.~Forms();
// game.~QApplication();
}
所以,有人可能会问,为什么不使Forms
类中的所有内容静态完成呢?由于静态类成员变量的寿命,这是不可能的。在 main()
启动之前,构建此类成员,然后在 main()
结束后破坏了。这是一个大问题,因为:
您无法利用智能指针到小部件,因为当
QApplication
不再存在时,它们将被删除,并且不允许。您可以手动reset()
手动指示,但这确实打败了智能指针的目的。智能指针在那里,因此您不必手动管理内存。由于
Forms
类没有实例 - 它只是静态成员的包装器 - 驱动器永远不会被调用,并且您无法利用C 自动清理成员。
您可以做的最多的是使所有方法成员变量 。因此,这仍然可以,但是使方法实现很麻烦:
class Forms {
Q_DISABLE_COPY(Forms)
QScopedPointer<LoginForm> m_loginForm;
QScopedPointer<WorldForm> m_worldForm;
static Forms * m_instance;
public:
Forms();
~Forms();
static Forms * instance();
static void login(int act = 0);
static void world();
};
void Forms::login(int act) {
Forms * inst = instance();
if (!inst->m_loginForm) inst->m_loginForm.reset(new LoginForm);
...
}
但这肯定是错误的:
// WRONG
class Forms {
static QScopedPointer<LoginForm> m_loginForm;
static QScopedPointer<WorldForm> m_worldForm;
public:
static void login(int act = 0);
static void world();
};
这是错误的,因为范围的指针被破坏,因此在main()
结束后删除了表格。周围没有QApplication
,您不允许使用小部件(甚至没有破坏它们)做任何事情。
要解决此问题,您需要在类似静态击路仪的方法中明确释放表单实例,您必须手动调用以删除表单。然后,您的主要内容将成为用C 语法编写的Delphi。您对Delphi成语有很大的偏见。这些成语不属于C - 您必须学习它们。C 编译器会在Delphi中进行大量代码生成。您应该利用这一点。
// AWKWARD: Delphi code in C++ syntax
int main(int argc, char *argv[]) {
QApplication game(argc, argv);
Forms::login();
int rc = game.exec();
Forms::destroy();
return rc;
}
// BRAINDEAD: Delphi code in C++ syntax
class Forms {
static QScopedPointer<LoginForm> m_loginForm;
static QScopedPointer<WorldForm> m_worldForm;
public:
static void login(int act = 0);
static void world();
static void destroy();
};
这希望可以解释为什么C 比Delphi更强大。在Delphi中,您必须担心C 编译器会照顾的很多事情,从而阻止您忘记重要的事情,例如释放记忆或发布其他资源。
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 在 2D 向量中使用第三个 [ ] 有什么意义?
- 如何通过按下第三个窗口中的按钮,将QString从一个窗口获取到另一个窗口
- 如何知道n!是否可以表示为三个连续数字的乘法?
- 我有三个 getline,但是一旦编译,输入就太多了
- 我遇到了黑客排名中的问题"TWO STRINGS"的三个测试用例的分段错误。原因是什么?
- 有没有更好的方法对C++中的三个整数进行排序?
- 如何检查第三个 API 是否在 Linux 中为 c/c++ 程序创建了一个新线程?
- 为什么 getch 在按下函数或箭头键时返回三个值?
- 使用三个数字比较器进行排序
- 我想在C++代码中比较这三个术语
- 我的动态链接队列在同一输出流中调用时不正确地输出三个返回函数
- 用于循环访问多个集合的数据结构
- 我该如何编码,使计算机知道两个名称条目和三个名称条目之间的区别
- 为什么我需要三个嵌套的大括号来调用赋值运算符,将const引用到二维数组
- 访问三个不同的变量在C++中形成三个不同函数中的一个文件
- 在C 中,可以从第三个共享对象访问其他两个不同共享对象
- 如何从另一个函数中访问一个功能,从C 中的第三个访问
- 在第三次调用中,当地址因本地作用域而被销毁时,temp2->next 如何能够访问第二个节点的地址?
- 访问三个静态数组比访问一个包含3倍数据的静态数组更快