C++ 关键字: extern

        Extern用作变量声明,而不是变量定义,变量赋值时前面不用加extern。

       在大型项目编程中,为了使代码结构清楚明了,往往会用不同的.h/.cpp文件来实现不同的功能模块。如果在模块A.h中定义了一个全局变量,在模块B.cpp中也想使用这个变量,此时就需要用到C/C++的关键字:extern。为什么必须要使用extern,因为C/C++有以下规则:

       同一个变量或函数,能且只能被定义一次,但是可以被多次声明。

       变量声明 规定了变量的类型和名字,定义还申请了存储空间,也可以给变量赋一个初始值。

       如果想声明一个变量而非定义它,就在变量名前添加关键字extern,而且不要显示地初始化变量。任何包含了显示初始化的声明即成为定义。我们能extern关键字标记的变量赋一个初始值,但是这么做也就抵消了extern的作用。extern语句如果包含初始值就不再是声明,而变成定义了。

extern int j;   // 声明j而非定义j
int j;       // 声明并定义j,定义会分配空间,而声明不会
extern int j = 0; // 虽然加了extern,但对其 显式初始化了,故此行 是 声明加定义j
void Fcunction_A(const unsigned int & _a); // 函数声明
void Fcunction_A(const unsigned int & _a) { /*..函数实现.*/ }; // 函数声明 + 定义
extern void Fcunction_A(const unsigned int & _a) { /*..函数实现.*/ }; //  函数声明 + 定义

      回到最初的问题,模块A.h 文件会被多个 文件 包含 (A.cpp 和B.cpp都想使用A.h中的变量,都会include A.h,如果A.h中的变量没有加extern,那就会在A.cpp 和B.cpp分别include时进行两次 声明+定义,导致多次定义 ),但 A.cpp只会编译一次,故如果想做一个全局变量,在 A.h文件中 只 声明,在A.cpp中进行定义。

       如以下的示例,test_A.h中声明了变量a和函数Function_A,test_A.cpp中进行了定义。test_B.cpp中想使用a或Function_A,有两种方式,使用前对变量a和函数Function_A再次声明,或者直接include test_A.h;声明之后,就可以在test_B.cpp中使用了。对于变量a,如果在test_A.h中不加extern,就会报mutilple definition of a的编译错误。Function_A 也一样,如果在test_A.h中声明+定义,也会报mutilple definition的错误。

//test_A.h
#ifndef _TEST_A_H_
#define _TEST_A_H_
#include <iostream>
extern unsigned int a;                    //noly declare here
void Fcunction_A(const unsigned int & _a);//only declare here
#endif

//test_A.cpp
#include "test_A.h"
unsigned int a = 10;   //defination here
void Fcunction_A(const unsigned int & _a) //defination here
{
    std::cout <<"here is Fcuntion_A, a = "<<std::dec <<a <<std::endl; 
    a = _a ;   
}

//test_B.h
#ifndef _TEST_B_H_
#define _TEST_B_H_
void Fcunction_B(); // declar
#endif

//test_B.cpp
#include "test_B.h"
#include <iostream>
using namespace std;
// test_B.cpp want to use a/Fcunction_A in A.h
// have two methods
// 1. 
extern unsigned int a;  //declare here
void Fcunction_A(const unsigned int & _a);//declare
// 2. 
// #include "test_A.h"
unsigned int b;     // declar & defination
void Fcunction_B()  // defination
{
    b = 100;
    Fcunction_A (b);
    cout <<"here is Fcuntion_B, a = "<<dec <<a <<endl;
}

//main.cpp
#include <iostream>
using namespace std;
// extern int j;   // 声明j而非定义j
// int j;       // 声明并定义j,定义会分配空间,而声明不会
// extern int j = 0; // 虽然加了extern,但对其 显式初始化了,故此行 是 声明加定义j
// void Fcunction_A(const unsigned int & _a); // 函数声明
// void Fcunction_A(const unsigned int & _a) { /*..函数实现.*/ }; // 函数声明 + 定义
// extern void Fcunction_A(const unsigned int & _a) { /*..函数实现.*/ }; //  函数声明 + 定义
#include "test_A.h"
#include "test_B.h"
int main(int argc, char** argv)
{
    Fcunction_B();
    return 0;
}

Result结果:

here is Fcuntion_A, a = 10

here is Fcuntion_B, a = 100

猜你喜欢

转载自blog.csdn.net/zgcjaxj/article/details/106297818
今日推荐