C++关键字“extern”和“static”

一)关键字:extern
1)基本用法:
首先,理解下面一段话的描述:
“单定义规则” one Definition Rule (ODR) 指出:变量只能有一次定义。
C++提供两种变量声明,一种是定义声明(defining declaration)或简称为定义,它给变量分配储存空间;另一种是引用声明(referencing declaration)或简称为声明(declaration),它不给变量分配储存空间,因为它引用已有的变量,引用声明使用关键字“extern”,且不进行初始化。
// 在文件1中定义全局对象

class MyClass 
{
    // 类的定义
};
MyClass global_obj;

// 在文件2中声明并使用全局对象

extern MyClass global_obj;
int main() 
{
    global_obj.some_member_function();
    return 0;
}

注意:在具体的函数内,局部变量能隐藏同名的全局变量。
2)特殊用法
1,与 C 语言代码的兼容:
当 C++ 代码需要调用 C 语言编写的函数或者使用 C 语言编写的库时,就需要使用extern “C”。因为 C++ 和 C 语言在函数名修饰(name mangling)上有不同的规则。C 语言没有函数名修饰,而 C++ 会对函数名进行修饰,这可能导致在 C++ 中链接 C 语言函数时找不到正确的函数。例如,有一个 C 语言编写的函数int myfunc(int a, int b)在myclib.c文件中,要在 C++ 文件中调用这个函数,在 C++ 文件的头文件或者源文件中需要这样声明:
cpp
extern “C”
{
int myfunc(int a, int b);
}
或者也可以这样写:
cpp
extern “C” int myfunc(int a, int b);
这样就告诉 C++ 编译器,myfunc这个函数应该按照 C 语言的方式进行链接,避免了因函数名修饰不同而导致的链接错误。
2,在 C++ 头文件中的应用:
在编写 C++ 头文件时,如果头文件可能会被 C 语言代码使用,或者头文件中的函数需要在 C 和 C++ 中都能正确链接,通常会使用extern "C"来包裹函数声明。例如:
cpp

#ifdef __cplusplus
extern "C" {
#endif
    int myheaderfunc(int a, int b);
#ifdef __cplusplus
}
#endif

这里__cplusplus是一个预定义的宏,当编译器在编译 C++ 代码时会定义这个宏。通过这种方式,当 C++ 代码包含这个头文件时,函数声明会被extern "C"包裹,按照 C 语言的方式进行链接;当 C 语言代码包含这个头文件时,extern "C"部分会被忽略(因为没有定义__cplusplus宏),函数声明也能正确使用。
二)关键字:static
有两种用法,(可以叫关键字重载),用于局部声明,以支持变量是无连接性的静态变量时,static表示的是存储持续性;用于全局声明时,static表示内部连接性(即不能在其他文件中用关键字“extern”引用声明此变量并使用),而变量已经是静态持续性了。
1)在 C 和 C++ 中变量的存储类型说明符(变量作用域和生命周期)
局部变量:
当static用于局部变量时,它改变了局部变量的存储类型和生命周期。普通的局部变量在函数调用结束后就会销毁,其生命周期仅限于函数执行期间。而static局部变量在函数第一次调用时初始化,并且在函数调用结束后不会销毁,它的生命周期贯穿整个程序的运行时间。例如:
c

#include <stdio.h>
void func() 
{
    static int static_var = 0;
    static_var++;
    printf("%d ", static_var);
}
int main() 
{
    func();
    func();
    func();
    return 0;
}

在这个例子中,static_var是一个static局部变量。每次调用func函数时,static_var的值都会保留,并且自增。程序的输出结果是1 2 3。这里强调一下:static int static_var = 0;语句只在第一次调用时执行一次,后面不再执行。
全局变量:
对于全局变量,static关键字将全局变量的作用域限制在定义它的源文件内。这意味着其他源文件不能访问这个被static修饰的全局变量。例如,在file1.c中有static int global_static_var = 10;,在file2.c中无法访问global_static_var,这样可以避免不同源文件中的同名变量相互干扰,起到了隐藏变量的作用,增强了程序的模块化和信息隐藏性。
2)在 C 和 C++ 中函数的存储类型说明符(函数作用域)
当static用于函数时,它使得函数的作用域仅限于定义它的源文件内,类似于static全局变量的效果。其他源文件不能调用这个被static修饰的函数。例如,在file1.c中有static int static_function(int a) { return a * 2; },在file2.c中不能调用static_function。这种方式也有助于将函数的使用范围限制在一个源文件内,便于程序的模块化和代码维护,防止外部文件对内部函数的不必要访问。
3)在 C++ 中类的成员变量和成员函数(类相关的特性)
成员变量:
在类中,static成员变量是被类的所有对象共享的。它不属于任何一个对象,而是属于整个类。static成员变量在类定义时声明,但是需要在类外进行定义和初始化(除了某些特殊情况,如const static整型成员变量可以在类内初始化)。例如:
cpp

class MyClass 
{
public:
    static int static_member_var;
    // 其他成员函数和成员变量
};
int MyClass::static_member_var = 0;

这里static_member_var是MyClass类的static成员变量,通过MyClass::static_member_var来访问,可以在任何一个MyClass对象之外访问和修改这个变量,并且所有MyClass对象共享这个变量的值。
成员函数:
static成员函数是属于整个类的,它没有this指针,不能访问非static成员变量和非static成员函数(因为没有this指针来确定对象)。static成员函数主要用于操作static成员变量或者执行与类相关的但不依赖于具体对象的操作。例如:
cpp

class MyClass 
{
public:
    static int static_member_var;
    static void static_member_func() 
    {
        static_member_var++;
    }
    // 其他成员函数和成员变量
};
int MyClass::static_member_var = 0;
int main() 
{
    MyClass::static_member_func();
    MyClass::static_member_func();
    std::cout << MyClass::static_member_var << std::endl;
    return 0;
}

在这个例子中,static_member_func是MyClass类的static成员函数,它可以直接访问和操作static成员变量static_member_var,程序输出为2。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值