簡體   English   中英

Qt C ++創建一個所有類都可以訪問的全局變量

[英]Qt C++ Create a Global Variable accessible to all classes

是否可以創建程序中所有類都可以全局訪問的變量,如果我從一個類更改它的值,其他所有類也將更改?

如果是這樣,我該如何實施?

每個人都一直在嘲笑“全球人是邪惡的”,但是我說幾乎所有東西都可以使用或濫用。 另外,如果全局變量本質上是壞的,那么根本就不會允許它們。 就全局變量而言,很可能會因誤用而導致非常負面的后果,但如果您真正知道自己在做什么,則可以100%罰款:

// globals.h - for including globals
extern int globalInt; // note the "extern" part

// globals.cpp - implementing the globals
int globalInt = 667;

使用命名空間來避免命名沖突並保持作用域更干凈也是一個很好的主意,除非您對命名約定特別謹慎,這是古老的“ C”命名空間方法。

另外,尤其是在使用多個線程的情況下,最好創建一個接口來訪問封裝的全局對象,該接口也將具有模塊化鎖,甚至在可能的情況下也可以是無鎖的(例如,直接使用原子)。

但是全球性並不一定是唯一的解決方案。 根據您的實際需求,單例或靜態類成員可能會成功完成這項工作,同時使其保持整潔並避免使用邪惡的全局變量。

如您所知,應避免使用全局變量。

但是您可以為全局變量創建一個頭文件,並在要使用它的每個位置創建#include“ globals.h”。然后可以正常使用每個變量。

如果僅在UI線程(對於QApplication ui應用程序)或主線程(對於QCoreApplication控制台應用程序)中使用此全局變量,那么編碼將很方便,並且可以設計自定義數據結構。但是,如果在多線程環境中使用它,您應該需要互斥或原子來保護全局變量。

此類變量必須在某處定義一次,然后在不同的編譯單元中使用。 但是,要使用某些東西,您需要告訴編譯器它已經存在(聲明)。 extern關鍵字使您可以聲明 其他 地方存在某些東西

為了構造您的代碼,您可以執行xkenshin14x (有點?)建議的方法:

全局

#pragma once

#include <string>

// Declaration
namespace global
{
    extern int i;
    extern float f;
    extern ::std::string s;
}

global.cpp

#include "global.h"

// Definition
namespace global
{
    int i = 100;
    float f = 20.0f;
    ::std::string s = "string";
}

main.cpp

#include "global.h"

int main(int argc, char *argv[])
{
    std::cout << global::i << " " << global::f << " " << global::s;
    return 0;
}

在這種情況下,最好使用名稱空間,因為它可以避免全局變量固有的名稱沖突。


或者,可以將所有全局填充封裝在一個“全局”對象中。 我引用了“全局”一詞,因為實際上該對象對於全局函數是靜態的,因此從技術上講, 不涉及全局變量 :)

這是僅標頭的實現:

全局

#pragma once

class Global
{
public:
    int i = 100;
    float f = 20.0f;
    // and other "global" variable 

public:
    Global() = default;
    Global(const Global&) = delete;
    Global(Global&&) = delete;

    static Global& Instance()
    {
        static Global global;
        return global;
    }
};

namespace {
    Global& global = Global::Instance();
}
// static Global& global = Global::Instance(); if you like

測試

#pragma once
#include "global.h"

struct Test 
{
    void ChangeGlobal() {
        global.i++;
    }
};

main.cpp

#include <iostream>

#include "global.h"
#include "test.h"

int main()
{
    Test t;
    std::cout << global.i << " " << global.f << std::endl;
    t.ChangeGlobal();
    std::cout << global.i << " " << global.f << std::endl;
    return 0;
}

這種方法至少有兩個好處:

  1. 您實際上不使用任何全局對象。
  2. 在您的Global類中,您可以在需要的地方添加帶有互斥體的變量訪問器。 例如, void SetSomething(const Something& something) { ... }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM