C++中static和extern的微妙细节
2010-05-06 18:40
113 查看
static和extern在C和C++中可以用来既可以修饰数据(变量和常量),还可以修饰函数。
如果用来修饰变量常量数据标识符,则static和extern的时间特性(存储特性)相同的,都是静态存储,存储在全局数据区,但是static是在定义时生成,而extern则是在程序执行前已经创建(早于main()函数执行),一直到程序结束销毁,但是static要早于extern,所以MFC采用全局xxApp类对象中main()启动程序,而Java语言采用静态Main类对象中main()启动程序都是可行的;而它们的空间特性(作用域)不同,static标识符是通常指局部数据(静态全局变量(常量)指是约束在内部变量(常量);静态局部变量和常量是块作用域;类静态数据成员则是类作用域,受类访问约束符控制,但是被所有类对象共享;不同于普通类数据成员每个类对象都要创建其内存副本),而extern标识符是全局数据(全局变量和常量,具有文件作用域,通过包含其声明文件,可以被其它文件访问,不能用于类数据成员)。
如果用来修饰函数,则static函数和extern函数的时间特性(存储特性)也是相同的,都是静态存储,也是程序执行时就已经存在内存;而其空间特性(作用域)不同,static指内部函数,局限在文件内部使用,而extern指外部函数,通过include头文件(接口),可以被其它文件使用。
实际使用要注意:static,extern通常加在变量、常量声明和函数声明前面,除非是定义和声明合二为一的,才加在定义前;一般在函数外部定义的都默认为extern全局的(变量、常量),普通函数也默认为extern(外部)的,因此要声明为静态变量、常量或者static内部函数必须显式指定,而且static内部函数通常声明在CPP文件中,以达到隐藏接口,防止和其它同名外部函数名字冲突。例如:
gloab.h
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
extern int Gloab_Int; //全部变量声明
#endif // TEST_H_INCLUDED
gloab.cpp
#include "gloab.h"
int Gloab_Int = 1000;
print.h
#ifndef PRINT_H_INCLUDED
#define PRINT_H_INCLUDED
extern void print();
#endif // PRINT_H_INCLUDED
print.cpp
#include "print.h"
#include "test.h"
#include
static void printStatic(); //内部接口必须在cpp文件中声明,或者先定义在调用。
void print()
{
Gloab_Int += 1000;
std::cout << "Gloab_Int = " << Gloab_Int << std::endl;
printStatic();
}
int gInit = 10; //全局变量没有在头文件声明释放接口,不能为外部文件使用,而且外部文件不能存在同名外部全局变量
static int sgInit = 100; //静态变量,表示其为内部变量,不能释放声明,为外部文件使用;
//可以存在同名的外部全局变量,只要不在本文件中直接或间接包含其头文件
void printStatic()
{
int iTemp = 0;
static int siVal = 1;
std::cout << "iTemp = " << iTemp++ << std::endl;
std::cout << "siVal = " << siVal++ << std::endl;
std::cout << "gInit = " << gInit++ << std::endl;
std::cout << "sgInit = " << sgInit++ << std::endl;
}
externprint.h
#ifndef EXTERNPRINT_H_INCLUDED
#define EXTERNPRINT_H_INCLUDED
extern void printStatic();
extern int sgInit; //和内部静态全局变量名字不冲突
//extern int gInit; //全局变量名字冲突
#endif // EXTERNPRINT_H_INCLUDED
externprint.cpp
#include "externPrint.h"
#include "test.h"
#include
int sgInit = 1;
//int gInit = 10;
void printStatic()
{
std::cout << "Gloab_Int = " << ++Gloab_Int << std::endl;
}
如果用来修饰变量常量数据标识符,则static和extern的时间特性(存储特性)相同的,都是静态存储,存储在全局数据区,但是static是在定义时生成,而extern则是在程序执行前已经创建(早于main()函数执行),一直到程序结束销毁,但是static要早于extern,所以MFC采用全局xxApp类对象中main()启动程序,而Java语言采用静态Main类对象中main()启动程序都是可行的;而它们的空间特性(作用域)不同,static标识符是通常指局部数据(静态全局变量(常量)指是约束在内部变量(常量);静态局部变量和常量是块作用域;类静态数据成员则是类作用域,受类访问约束符控制,但是被所有类对象共享;不同于普通类数据成员每个类对象都要创建其内存副本),而extern标识符是全局数据(全局变量和常量,具有文件作用域,通过包含其声明文件,可以被其它文件访问,不能用于类数据成员)。
如果用来修饰函数,则static函数和extern函数的时间特性(存储特性)也是相同的,都是静态存储,也是程序执行时就已经存在内存;而其空间特性(作用域)不同,static指内部函数,局限在文件内部使用,而extern指外部函数,通过include头文件(接口),可以被其它文件使用。
实际使用要注意:static,extern通常加在变量、常量声明和函数声明前面,除非是定义和声明合二为一的,才加在定义前;一般在函数外部定义的都默认为extern全局的(变量、常量),普通函数也默认为extern(外部)的,因此要声明为静态变量、常量或者static内部函数必须显式指定,而且static内部函数通常声明在CPP文件中,以达到隐藏接口,防止和其它同名外部函数名字冲突。例如:
gloab.h
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
extern int Gloab_Int; //全部变量声明
#endif // TEST_H_INCLUDED
gloab.cpp
#include "gloab.h"
int Gloab_Int = 1000;
print.h
#ifndef PRINT_H_INCLUDED
#define PRINT_H_INCLUDED
extern void print();
#endif // PRINT_H_INCLUDED
print.cpp
#include "print.h"
#include "test.h"
#include
static void printStatic(); //内部接口必须在cpp文件中声明,或者先定义在调用。
void print()
{
Gloab_Int += 1000;
std::cout << "Gloab_Int = " << Gloab_Int << std::endl;
printStatic();
}
int gInit = 10; //全局变量没有在头文件声明释放接口,不能为外部文件使用,而且外部文件不能存在同名外部全局变量
static int sgInit = 100; //静态变量,表示其为内部变量,不能释放声明,为外部文件使用;
//可以存在同名的外部全局变量,只要不在本文件中直接或间接包含其头文件
void printStatic()
{
int iTemp = 0;
static int siVal = 1;
std::cout << "iTemp = " << iTemp++ << std::endl;
std::cout << "siVal = " << siVal++ << std::endl;
std::cout << "gInit = " << gInit++ << std::endl;
std::cout << "sgInit = " << sgInit++ << std::endl;
}
externprint.h
#ifndef EXTERNPRINT_H_INCLUDED
#define EXTERNPRINT_H_INCLUDED
extern void printStatic();
extern int sgInit; //和内部静态全局变量名字不冲突
//extern int gInit; //全局变量名字冲突
#endif // EXTERNPRINT_H_INCLUDED
externprint.cpp
#include "externPrint.h"
#include "test.h"
#include
int sgInit = 1;
//int gInit = 10;
void printStatic()
{
std::cout << "Gloab_Int = " << ++Gloab_Int << std::endl;
}
相关文章推荐
- C++ 学习 (static, extern)
- 浅谈C/C++中的static和extern关键字
- c/c++中extern、static、const的用法及全局变量/常量
- C++ 中 static 和 extern关键字
- C/C++中inline/static inline/extern inline的区别及使用
- C/C++中auto、static、register、extern关键字区别小结
- C++中的extern/static
- 转载 浅谈C/C++中的static和extern关键字
- 【c/c++】multiple definition-->static & extern
- C/C++中修饰符const、extern、static、volatile的用法
- C/C++ static , extern关键字
- C/C++中 const,extern,static,volatile的使用 200
- C/C++中修饰符const、extern、static、volatile的用法【解决了】
- C++中extern与static的用法
- C++ 基础内容2,c++ 中的static 和 extern
- C/C++中auto、static、register、extern关键字区别小结
- C++那些细节--static_cast,dynamic_cast,const_casst,reinterpret_cast
- C/C++中inline/static inline/extern inline的区别及使用
- C/C++中 const,extern,static,volatile的使用
- C++ 修饰符const、static、extern、ref、volatile、explicit总结