一、不要将全局变量定义在头文件
如果将全局变量定义在头文件中,该头文件被其他文件包含会报“找到一个或多个多重定义的”错误。其他文件包含该头文件后相当于都定义了一个全局变量符号。假设有文件file1.h,file1.cpp,如下:
// file1.h
#pragma once
int aa = 0;
class file1
{
public:
file1();
~file1();
};
// file1.cpp
#include "file1.h"
file1::file1()
{
}
file1::~file1()
{
}
现在在main.cpp中再包含file.h,就会报错。
#include "stdafx.h"
#include "file1.h"
int main()
{
return 0;
}
为了解决上面方式可以将全局变量定义在file1.cpp中,其他文件或模块使用该变量时使用extern声明该变量为全局变量即可。如下:
// file1.cpp
#include "file1.h"
int aa = 0;
file1::file1()
{
}
file1::~file1()
{
}
// main.cpp
#include "stdafx.h"
#include "file1.h"
int main()
{
extern int aa;
aa = 89;
return 0;
}
二、不要修改static全局变量
一般全局变量定义后,在整个程序中都能访问,但是静态全局变量只在本文件中有效,除非外部文件包含该文件。这包含几层意思:
1)static变量如果定义在cpp中,不能通过extern方式在外部访问;
2)如果static变量定义在头文件中,其他模块包含该头文件不会产生重复定义符号问题;
3)但是其他模块可以访问该变量,但是不能修改该变量。
针对第1)点比较好理解,在file1.cpp中定义static全局变量,无法在main.cpp访问,如下:
// file1.cpp
#include "file1.h"
static int a = 90;
file1::file1()
{
}
file1::~file1()
{
}
// main.cpp
#include "file1.h"
using namespace std;
int main()
{
extern int a;
a = 39;
system("pause");
return 0;
}
针对第2)3)点,如果static全局变量是定义在头文件中的,其他模块通过包含该头文件,不会产生重复定义符号错误。
可以理解为当模块应用static全局变量时,程序单独为该模块创建了一个变量区域,因此试图通过其他模块修改static全局变量是不会成功的。如下:
// file1.h
static int a = 90;
class file1
{
public:
file1();
~file1();
};
// file1.cpp
#include "file1.h"
#include <iostream>
file1::file1()
{
std::cout << a << std::endl; // 打印a
}
file1::~file1()
{
}
// file2.cpp 在另外一个文件中试图改变a
#include "file2.h"
#include "file1.h"
#include <iostream>
file2::file2()
{
a = 69; // 改变a
std::cout << a << std::endl; // 输出69,仅在该文件中改变a值
}
file2::~file2()
{
}
// main.cpp
#include "file1.h"
#include "file2.h"
using namespace std;
int main()
{
a = 111; // 在main文件中改变a值
file2 f; // 试图改变a为69
cout << a << endl; // a在main文件中值还是111
file1 f2; // 在file1文件中的值为90
system("pause");
return 0;
}
从上面可以知道static全局变量在其他模块仅看作变量的副本,不能试图修改static全局变量来修改。故最好可以将static定义为const形式,如static const int a = 90。