繁体   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