C++ 如何从一个函数访问另一个函数中的内容,在c++;

C++ 如何从一个函数访问另一个函数中的内容,在c++;,c++,qt,function,class,C++,Qt,Function,Class,我有以下代码: void Forms::login() { LoginForm *loginForm = new LoginForm; loginForm->show(); } void Forms::startGame() { WorldForm *worldForm = new WorldForm; worldForm->show(); loginForm->hide(); } 因此,我试图将所有逻辑绑定到一个单独的文件,如log

我有以下代码:

void Forms::login() {
    LoginForm *loginForm = new LoginForm;
    loginForm->show();
}

void Forms::startGame() {
    WorldForm *worldForm = new WorldForm;
    worldForm->show();
    loginForm->hide();
}
因此,我试图将所有逻辑绑定到一个单独的文件,如logics.cpp。首先,我只使用常规函数,但我无法从startGame访问loginForm(因为我不能简单地将其添加到.h文件中,这会使所有程序崩溃,不要问为什么-Qt之类的东西。这些类型是QWidgets)。现在我需要的是:

  • 如何将WorldForm和LoginForm的声明添加到类表单的根(或头文件),我不能这样做

  • 最后一个目标是从另一个文件中的另一个类调用startGame()(或者,在本例中,作为静态函数调用Forms::startGame()),startGame()应该能够隐藏loginForm,正如上面所示

  • 我甚至不能这样做:

    void Forms::world(int a) {
        WorldForm *worldForm = new WorldForm;
        if(a==0) {
            worldForm->show();
        }else{
            worldForm->hide();
        }
    }
    
    因为我只需要创建一次
    worldForm
    ,这将为每个调用创建大量实例1


    这是我的代码:

    您要查找的是成员变量和以
    QApplication
    样式完成的单例模式

    您似乎正在声明小部件类型的全局变量:

    // interface (.h)
    extern QWidget myWidget;
    // implementation (.cpp)
    QWidget myWidget;
    
    这永远不会起作用,因为这样一个对象的构造发生在
    main()
    开始之前主体()> /Cord>执行的。您需要使用指针

    表单
    类可以如下所示声明和实现

    类是不可复制的,因为
    QScopedPointer
    是不可复制的,所以我们应该为人类读者明确它。无论如何,这个类是可复制的并没有什么好的理由,即使我们使用了
    QSharedPointer

    使用
    QScopedPointer
    智能指针以避免表单泄漏。
    QScopedPointer
    的析构函数自动释放分配的表单(如果有)。它可以用作布尔值,当它为非null时为真

    该类强制执行一个不变量,即它只有一个实例。该实例应该在
    QApplication
    之后的
    main()
    函数中构造。您可以使用static
    Forms::instance()
    方法从任何地方访问此实例

    例如,在
    LoginForm::on\u loadButton\u clicked()
    中,您可以使用

    Forms::instance()->world();
    
    //core.h-接口
    #包括
    类LoginForm;
    阶级世界形态;
    班级形式{
    Q_禁用_复制(表格)
    QScopedPointer m_loginForm;
    QScopedPointer m_worldForm;
    静态表单*m_实例;//声明
    公众:
    形式();
    ~Forms();
    静态表单*instance();
    无效登录(int act=0);
    空虚的世界();
    };
    //forms.cpp-实施
    #包括“core.h”
    #包括“Forms/loginform.h”
    #包括“Forms/worldform.h”
    Forms*Forms::m_实例=0;//定义
    //运行时默认值构造静态类成员,因此在技术上
    //无需对空指针进行显式初始化。
    void表单::登录(int-act){
    如果(!m_loginForm)m_loginForm.reset(新loginForm);
    开关(act){
    案例1:
    m_loginForm->hide();
    打破
    违约:
    m_loginForm->show();
    }
    }
    void表单::world(){
    如果(!m_worldForm)m_worldForm.reset(新世界形态);
    m_worldForm->show();
    }
    表单::表单(){
    Q_断言(!m_实例);
    m_实例=此;
    }
    表单::~Forms(){
    m_实例=0;
    }
    Forms*Forms::instance(){
    返回m_实例;
    }
    //main.cpp
    #包括
    #包括“Classes/core.h”
    int main(int argc,char*argv[]){
    QApplication游戏(argc、argv);
    形式;
    forms.login();
    return game.exec();
    //本地对象实例在C++生成的代码中被销毁。
    //毁灭的顺序与定义的顺序相反。
    //编译器将以下代码放在“此处”:
    //形式。~forms();
    //游戏。~QApplication();
    }
    
    因此,有人可能会问,为什么不让
    表单中的所有内容都是静态的,然后用它来完成呢?由于静态类成员变量的生命周期,这实际上是不可能的。这些成员在
    main()
    开始之前构造,在
    main()
    结束之后销毁。这是一个大问题,因为:

  • 您不能利用小部件的智能指针,因为当
    QApplication
    不再存在时,它们将被删除,这是不允许的。您可以手动
    reset()
    这些指针,但这实际上违背了智能指针的目的。智能指针的存在使您不必手动管理内存

  • 因为没有<代码>表单类-它只是静态成员的包装器——析构函数永远不会被调用,并且不能利用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);
        ...
    }
    

    <>这有助于解释为什么C++是比Delphi更强大的语言。在Delphi中,您必须担心C++编译器所关心的许多事情,防止您忘记一些重要的东西,比如释放内存或释放其他资源。< / P>您可以做<代码>静态Word表单= Word表单=新Word表单;
    只创建一次,但我不明白为什么不能在头文件中包含这些定义(我在Qt中做过很多次)。你能发布代码或者一个例子来解释原因吗?在我看来,您对整个程序的结构设置不正确。它不需要是静态的(不应该是静态的),它只需要是表单的一个成员,而不是每次都在方法中本地创建。我不能将此包含到头文件中,因为LoginForm和
    
    // WRONG
    class Forms {
        static QScopedPointer<LoginForm> m_loginForm;
        static QScopedPointer<WorldForm> m_worldForm;
    public:
        static void login(int act = 0);
        static void world();
    };
    
    // 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();
    };