是否有可能为我的程序中的所有类创建一个全局可访问的变量,如果我从一个类更改它的值,它也会为所有其他类更改?
如果是这样,我该如何实现?
答案 0 :(得分:5)
每个人都一直在喋喋不休地认为全球化是邪恶的,但是我说几乎所有东西都可以使用或滥用。此外,如果全局性本质上是坏的,他们根本就不会被允许。在全局变量的情况下,很有可能意外误用非常消极的后果,但如果你真的知道自己在做什么,它们就会100%罚款:
// globals.h - for including globals
extern int globalInt; // note the "extern" part
// globals.cpp - implementing the globals
int globalInt = 667;
使用命名空间来避免命名冲突并保持范围更清晰也是一个非常好的主意,除非您对命名约定特别细致,这是旧的" C"做命名空间的方法。
此外,特别是如果您使用多个线程,最好创建一个接口来访问封装的全局内容,这些内容也将具有模块化锁定,甚至可以在任何可能的情况下锁定(例如直接使用原子公司)。
但全球化不一定是唯一的解决方案。根据你真正需要的东西,单身人士或静态班级成员可以做到这一点,同时保持它更整洁,避免使用邪恶的全局。
答案 1 :(得分:1)
您可能知道应该避免使用全局变量。
但是你可以在你想要使用它的每个地方为全局变量和#include“globals.h”创建一个头文件。然后你可以正常使用每个变量。
答案 2 :(得分:0)
如果您只是在UI线程(对于QApplication ui app)或主线程(对于QCoreApplication控制台应用程序)中使用此全局变量,那么编写代码会很方便,您可以设计自定义数据结构。但是如果您在多线程环境,你应该需要互斥或原子来保护全局变量。
答案 3 :(得分:0)
这样的变量必须在某处定义,然后在不同的编译单元中使用。但是,为了使用某些东西,您需要告诉编译器它是否存在(声明它)。 extern
关键字可让您声明 。
为了构建代码,您可以执行 xkenshin14x (有点?)建议:
global.h
#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;
}
在这种情况下使用命名空间是很好的,因为它可以避免全局变量固有的名称冲突。
或者,可以将所有全局内容封装在一个“全局”对象中。我引用了“全局”这个词,因为这个对象确实是一个全局函数是静态的,所以技术上没有涉及全局变量:)
以下是仅限标题的实现:
global.h
#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
test.h
#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;
}
这种方法至少有两个好处:
Global
类中,您可以在需要的地方添加带有互斥锁的变量访问器。例如,void SetSomething(const Something& something) { ... }