2017-08-17 200 views
1

是否有可能创建一个变量全局访问我的程序中的所有类,如果我改变它的值从一个类它也将改变所有其他类?Qt C++创建一个全局变量可访问所有类

如果是这样,我该如何实现?

+0

是的,为什么你不应该这样做:https://stackoverflow.com/questions/484635/are-global-variables-bad – MrEricSir

回答

1

每个人都在喋喋不休地说“全局变种是邪恶的”,但我说几乎所有的东西都可以被使用或被滥用。另外,如果globals本质上是坏的,他们根本就不会被允许摆在首位。在全局的情况下,有一个偶然的误操作非常消极的后果相当的潜力,但他们是100%的罚款,如果你真的知道你在做什么:

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

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

它也可能是一个非常不错的主意使用命名空间避免命名冲突并保持范围更清晰,除非您对命名约定特别谨慎,这是命名空间的老式“C”方式。

另外,特别是如果您使用多个线程,创建一个接口来访问封装的全局内容也是一个好主意,这些内容也将具有模块化锁定,或者尽可能无锁定地使用(例如直接使用原子)。

但是全球并不一定是唯一的解决方案。根据你真正需要的东西,单身人士或者静态类成员可能会这样做,同时保持它更整洁一些,避免使用邪恶的全局变量。

0

如果您只是在UI线程(用于QApplication ui应用程序)或主线程(用于QCoreApplication控制台应用程序)中使用此全局变量,那么编码会很方便,您可以设计一个自定义数据结构。但是如果使用它在多线程环境中,您应该需要互斥锁或原子来保护全局变量。

+2

你认为你可以帮我一个例子的实现吗? –

1

应该尽量避免使用全局变量。

但是你可以在你想要使用它的每个地方为全局变量和#include“globals.h”创建头文件。然后你可以正常使用每个变量。

+1

但是不会重新定义它包含在每个类中的变量? –

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; 
} 

有一个这样的做法至少有两个好处:

  1. 您不要随便使用任何全局对象。
  2. 在您的Global类中,您可以在需要的地方添加带有互斥锁的变量存取器。例如,void SetSomething(const Something& something) { ... }
+0

之前(而不是/之后)downvoting你可以写评论有关这个问题,我一定会修复它。 – WindyFields