04-05-2005 por niTsumuji
Como definir variáveis globais em C++?
Como posso fazer para definir variáveis globais em C++? Estou tentando aqui usando um .h, mas se uma classe altera o valor de uma variável lá, outra classe não pega esse valor novo.
Tipo, a nova classe reinicializa a variável. Talvez porque eu esteja incluindo o .h novamente na outra classs?
04-05-2005 por kao00
Se não me engano, vc tem que usar o operador :: antes do nome da variável global para modifica-lá ou referir a ela.
Pensando bem, acho que o operador só é necessário quando se tem uma variável global e uma local com o mesmo nome. Mas tente ai, talvez seja isso mesmo.
04-05-2005 por niTsumuji
Compilar compilou, mas dá na mesma que não colocar o operador.
04-05-2005 por jackinabox
Que tal colocar uma declaração
extern em um .H (
extern int myglobalvar;), declará-la em um CPP (
int myglobalvar;), e incluir o .H que contém a declaração
extern em todos os .CPP que precisam acessar essa variável?
04-05-2005 por jqueiroz
Citação:
|
Postado Originalmente por jackinabox
Que tal colocar uma declaração extern em um .H (extern int myglobalvar  , declará-la em um CPP (int myglobalvar  , e incluir o .H que contém a declaração extern em todos os .CPP que precisam acessar essa variável?
|
Foi assim que eu fiz no meu projeto final (C++). Eu tinha um "vars.cpp" e um "vars.h"...
04-05-2005 por pflynn
São duas coisas diferentes: uma coisa é
definir a variável, outra é
declará-la. Normalmente isso é feito de uma vêz só (definicão e declaracão), mas se for utilizar variáveis globais (que muitos programadores com tendências fortes de OO odeiam), faca como sugeriram o jqueiroz e o jackinabox: defina a variável num arquivo .cpp e declare a como externa onde mais puder ser utilizada.
05-05-2005 por niTsumuji
Beleza, vou tentar isso.
06-05-2005 por niTsumuji
Essa variável tem que ser um membro direto da classe certo? Por que se eu puser como uma variável de um método, eu tenho esse erro:
In function `engine::engine[not-in-charge]()':
: undefined reference to `FPS'
FPS é a variável.
06-05-2005 por k4z1nh0
nao entendi direito sua pergunta, mas se sua duvida esta em declarar variaveis globais, ou seja sao declaradas fora de todas as funções, ja variaveis locais sao criadas sempre dentro de funcoes e soh sao visualizadas por meio dakela funcao.
variaveis externas sao compartilhadas por todos os programas fontes que utilizam a linkedicao incluindo seu respectivo arquivo.
portanto pode tentar utilizar o que o jackinabox disse.
Espero ter ajudado.
06-05-2005 por jackinabox
Citação:
|
Postado Originalmente por niTsumuji
Essa variável tem que ser um membro direto da classe certo?
|
Ooops... Estamos falando de uma variável global ou de uma variável membro?
Citação:
|
Por que se eu puser como uma variável de um método, eu tenho esse erro: ...
|
Ooops de novo... Estamos falando de uma variável global ou de uma variável local (de um método)?
Agora não entendi mais...
06-05-2005 por niTsumuji
A variável tem de ser global, mas a sua declaração tem de ser feita no .cpp, na classe, não é mesmo? Essa declaração é feita direto como membro da classe, ou pode ser de dentro de um método da classe?
Assim:
globais.h
class1.cpp
Código:
#include "globais.h"
...
class class1{
private:
float FPS;
...
void metodo(void){};
...
06-05-2005 por jackinabox
Ooops: Editado, pois a inicialização da variável no meu exemplo estava no local errado 
ops:
Citação:
|
Postado Originalmente por niTsumuji
A variável tem de ser global, mas a sua declaração tem de ser feita no .cpp, na classe, não é mesmo? Essa declaração é feita direto como membro da classe, ou pode ser de dentro de um método da classe?
|
niTsumuji:
Se a variável é
global, isso significa que ela não será declarada nem como membro da classe, e nem dentro de um método da classe.
Variáveis declaradas dentro de um método são variáveis locais, e variáveis declaradas como membros da classe são variáveis membro, e
esses termos são excludentes. Não existe algo como "variável global membro" ou "variável global local".
Pode haver "várias variantes" relacionadas a onde declarar e onde definir a variável global. Segue um exemplo:
globais.h
Código:
extern float fps; // declaração da variável (linkagem externa)
class1.cpp
Código:
#include "globais.h"
float fps = 24; // definição da variável
void Class1::metodo1()
{
// ...
fps = 30;
}
07-05-2005 por jqueiroz
talvez ele esteja se confundindo com a visibilidade dos atributos (variáveis membros)... atributos públicos, privados, etc...
07-05-2005 por jackinabox
Citação:
|
Postado Originalmente por jqueiroz
talvez ele esteja se confundindo com a visibilidade dos atributos (variáveis membros)... atributos públicos, privados...
|
Ah, pode ser.
Ei,
niTsumuji: Dê uma olhada no meu post anterior, pois fiz uma correção no código!
07-05-2005 por jackinabox
Citação:
|
Postado Originalmente por jqueiroz
talvez ele esteja se confundindo com a visibilidade dos atributos (variáveis membros)... atributos públicos, privados...
|
Hummm... então talvez o
niTsumuji não queira
realmente declarar uma variável global, mas sim fazer outra coisa relacionada à visibilidade/acessibilidade :?:
09-05-2005 por niTsumuji
hum, coloquei pra testar pra valer e veja só:
classe1.cpp
Código:
#include <iostream>
#include "global.h"
#include "classe1.h"
int y;
void classe1::print(void){
y = 3;
std::cout << "C1: " << y << std::endl;
}
classe1.h
Código:
//#include <iostream>
//#include "global.h"
class classe1{
public:
void print(void);
};
classe2.cpp
Código:
#include <iostream>
#include "global.h"
#include "classe2.h"
int y;
void classe2::print(void){
std::cout << "C2: " << y << std::endl;
}
classe2.h
Código:
//#include <iostream>
//#include "global.h"
class classe2{
public:
void print(void);
};
extern int y;
main
Código:
#include "classe1.h"
#include "classe2.h"
int main(){
classe1 objClasse1;
classe2 objClasse2;
objClasse1.print();
objClasse2.print();
return 0;
}
Na hora de compilar:
g++ -c main.cpp
g++ -c classe1.cpp
g++ -c classe2.cpp
g++ main.o classe1.o classe2.o
classe2.o(.bss+0x0): multiple definition of `y'
classe1.o(.bss+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [all] Error 1
Se colocar a definição nos .cpp dá esse erro. Se colocar nos .h também. Não tem jeito disso aí funcionar!
O que eu quero é simplemente fazer as classes enchergarem a mesma variável.
09-05-2005 por jackinabox
Citação:
|
Postado Originalmente por niTsumuji
Se colocar a definição nos .cpp dá esse erro. Se colocar nos .h também. Não tem jeito disso aí funcionar!
O que eu quero é simplemente fazer as classes enchergarem a mesma variável.
|
Assim não vai funcionar mesmo, e o compilador está dizendo qual é a causa do problema:
classe2.o(.bss+0x0): multiple definition of `y'
classe1.o(.bss+0x0): first defined here
Você pode
declarar uma variável mais de uma vez, mas somente pode definí-la
uma única vez.
Você está
definindo a variável
y 2 vezes, o que é ilegal:
classe1.cpp:
classe2.cpp:
Apenas um dos CPPs deve conter essa definição. E todos os CPPs que precisarem da
declaração de
y, deveriam conter um
#include do .H onde está a declaração
extern int y.
09-05-2005 por niTsumuji
Cara que troço confuso. Quer dizer que eu tenho que definí-la uma única vez em qualquer lugar(achei preferencialmente melhor no main.cpp), e sair usando...
Acho que vou ficar tonto, mas deu certo!
Valeu aí pessoal! Essa eu não ia adivinhar nunca!
09-05-2005 por jqueiroz
Faça +/- assim:
global.h:
global.cpp:
Código:
#include "global.h"
int y;
classe1.h:
Código:
class classe1{
public:
void print(void);
};
classe1.cpp:
Código:
#include <iostream>
#include "global.h" /* <- aqui o y é definido */
void classe1::print(void){
y = 3;
std::cout << "C1: " << y << std::endl;
}
Vê só que eu não incluo "global.h" em "classe1.h" --- afinal, lá eu não vou referenciar nenhuma variável global.
Veja tb que eu não declaro "y" em nenhum lugar de classe1.cpp, pois essa declaração vem toda de "global.h".
09-05-2005 por jackinabox
A maneira sugerida pelo
jqueiroz é uma boa alternativa, pois organiza suas variáveis globais em dois arquivos: a declaração em um .H dedicado para variáveis globais e a definição em um .CPP também dedicado.
Conforme eu havia comentado em post anterior, você pode organizar o acesso a uma variável global de diversas maneiras diferentes. Em um sistema que eu escrevi, por exemplo, a variável global é uma instância de uma classe (e não um
int, como no nosso exemplo). Nesse caso, eu optei por uma organização diferente. Como pode ser difícil de entender esse meu exemplo real, vou dar um exemplo fake correspondente:
Digamos que você tenha um sistema com 200 classes. Existe apenas uma instância de uma dessas classes, e essa instância deve ser acessada por várias outras classes. Então uma opção seria declarar essa instância como uma variável global (uugghh, dê-lhe acoplamento -
don't try this at home).
Vamos considerar que essa classe seja a classe
Scanner (um desses scanners de supermercado, que serve para ler o código de barras dos produtos).
class Scanner.h:
Código:
class Scanner
{
public:
void Habilitar();
void Desabilitar();
// etc...
};
extern Scanner* scanner;
Scanner.cpp:
Código:
#include "Scanner.h"
Scanner* scanner = new Scanner();
void Scanner::Habilitar()
{
// código para habilitar o scanner
}
void Scanner::Desabilitar()
{
// código para desabilitar o scanner
}
OutraClasse.cpp
Código:
#include "Scanner.h"
#include "OutraClasse.h"
void OutraClasse::MetodoQualquer()
{
scanner->Habilitar();
}
MaisUmaClasse.cpp
Código:
#include "Scanner.h"
#include "MaisUmaClasse.h"
void MaisUmaClasse::MaisUmMetodoQualquer()
{
scanner->Habilitar();
}
Na realidade, muita gente fica dias tentando fazer funcionar coisas como essa, e aí entra o conhecimento básico, que tanto comentamos aqui no fórum. Se você entender os princípios - nesse caso: diferença entre
declaração e
definição, noções básicas sobre o processo de linkagem, etc. - vai ficar fácil entender por que motivo você não pode definir a variável mais de uma vez, e também quais seriam as opções para declarar e definir uma variável global.
Tentando resumir:
- Coloque a declaração
extern em um lugar onde as outras classes interessadas possam incluir essa declaração (o que permitirá que o compilador identifique o tipo da variável em todos os pontos em que ela for referenciada).
- Defina a variável apenas em um dos módulos do conjunto de arquivos (o que permitirá que o linker resolva as referências àquela variável).