案例:
variables.h文件
#include<iostream>
//#include<string>
using namespace std;
void input();//函数申明
const int var=100;//
定义
一个const变量,
extern int Max;//
申明
变量Max,一个变量可以有多次申明,但只能有一次定义
main.cpp文件
#include”variables.h”
int Max=10;//
变量
Max定义
extern const int Var1=20;//
定义
一个const变量
void main()
{
int sum=0;
for(int i=0;i<Max;i++)
sum+=i;
cout<<“main Max=”<<Max<<” sum=”<<sum<<endl;
cout<<“main var=”<<var<<” var address=”<<&var<<endl;
cout<<“main Var1=”<<Var1<<” Var1 address=”<<&Var1<<endl;
cout<<“*******************************”<<endl;
input();
}
member.cpp文件
#include”variables.h”
extern const int Var1;//
申明
变量
void input()
{
int Number=0;
for(int i=0;i<Max;i++)
Number+=i;
cout<<“input Max=”<<Max<<” Number=”<<Number<<endl;
cout<<“input var=”<<var<<” var address=”<<&var<<endl;
cout<<“input Var1=”<<Var1<<” Var1 address=”<<&Var1<<endl;
}
解释:
/*
头文件设计
头文件只能包含申明、不能包含定义。但有三个例外:
1、头文件可以定义
类
2、头文件可以定义在编译时就知道值的const变量
3、
inline函数
(内联函数)
默认情况下,在cpp文件中定义的非const变量,可以通过加extern在别的cpp文件进行访问,
如本利中的main函数中定义 int Max,
而在cpp文件中定义的const变量要想被别的文件访问,
在定义时
就必须显示的指定为extern,
如本例中的extern const int Var1
特别需要注意本例中的头文件中定义的const int var=100和main函数中定义的extern const int Var1对比。都是定义了一个const变量,只是定义的地方不一样。
共同点:两个 const 变量多可以在 mian.cpp文件和member.cpp文件中访问,即被别的文件访问。
不同点:
(1)头文件中的const int var=100 是利用了编译器的特例, mian.cpp文件和member.cpp文件
调用var时通过 #include”variables.h”就能成功, 猜想:其实在mian.cpp文件和member.cpp文件中
调用的不是同一个Var,只是在这两个函数中都重新定义了一个名称相同的var变量,且值也相同,
在本例中 cout<<“input var=”<<var<<” var address=”<<&var<<endl; cout<<“main var=”<<var<<” var address=”<<&var<<endl;
输出的两个var地址是不一样的
。证明这个猜想是正确的。这似乎和“一个变量只能定义一次规则”
相矛盾,事实不是这样的,这就和const 的特殊性有关了,
全局作用域内定义的const变量其正真的
作用域是定义这个const变量的文件作用域
。那么在多个文件汇中包含相同的文件名就不会有冲突了。
这同样告诉我们为什么费const不能定义在头文件中的道理,因为全局作用域内定义的非const变量,
作用域是真正的全局,那么如果把非const变量定义在头文件中,mian.cpp文件和member.cpp文件
调用头文件时,这样就会导致全局作用域内的命名冲突,因此
要想多个文件公用一个非const变量,可以利用头文件中加申明的方式实现:本例中extern int Max
(2)mian.cpp文件中的extern const int Var1;是通过强制将变量Var作用域变为真正的全局,这样在
member.cpp访问到的Var1和mian.cpp文件中Var1是同一个变量:
cout<<“main Var1=”<<Var1<<” Var1 address=”<<&Var1<<endl;
cout<<“input Var1=”<<Var1<<” Var1 address=”<<&Var1<<endl;
两个输出的Var1 address是相同的。
*/