C++中的static使用

本文详细解析了C++中static关键字的两个主要用途:静态存储和控制连接。介绍了如何利用static实现变量在函数调用间保持值、定义静态数据成员及静态成员函数,并展示了通过static控制名字的可见性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++的static可以控制存储和可见性。


static基本含义:

1、静态存储。在静态数据区上创建,而不是每次函数调用时在堆上产生。

2、控制连接。static控制名字的可见性(visibility),对于特定的编译单位来说是局部的,所以这个名字在这个文件单元或者类之外是不可见的。


1、静态存储

用法:

函数内的静态变量:可以在函数调用之间保留一个变量的值,由于静态变量存储在静态数据区中,可以在调用之间保持它的值。

如果没有为一个内部的静态变量提供一个初始值,编译器会确保在程序开始时他被初始化为0(转化为适当的类型)。对于函数中的静态变量,既然是为了隐藏,就在函数体内声明的时候定义:如 static char* s = NULL; ,初始化只且仅会在函数第一次调用时执行一次。


a) C++中的静态数据成员存储

class A{

    static int i;

public:
    // ...
};


之后必须在定义文件中为静态数据成员定义存储区:

int A::i = 1; 

A::i定义为私有的依然可以初始化,因为其只有定义时才可这么初始化,保证了绝对安全。如果静态数据成员是一个带构造函数的对象,可以调用定义的构造函数来代替 = ,如果没有,会调用默认的。

若为静态常量,可以在类体内定义。如static int i = 1;


当静态数据成员为数组时,初始化必须在外部进行定义。

如:

class X{
    int i;
public:
    X (int ii):i(ii){}
};

class Stat{
    static X x1;
    staic X xtable[];
};

X Stat::x1(100);

X Stat::xtable[]={X(1), X(2), X(3)};

int main(){
    Stat v;  
    //~
    return 0;
}

b) 静态成员函数

静态成员函数为类的全体对象服务,减少了全局名字空间的占用,需要用任何具体的对象。

class X{
public:
    static void f(){};
};

int main(){

    X::f();

    //~
}


当然也可以用对象来访问。

static 成员函数只能访问静态数据成员和静态成员函数。对于一个对象来说,当前对象的地址this被隐式地传递到函数,但静态成员函数没有this,所以无法访问一般的成员。


c)一个有趣的使用

可以把一个类的静态数据成员放到此类的内部,然后把构造函数和拷贝构造函数(手动增加)设置为私有的,这样一个类只有唯一的对象,可以访问,却不能产生任何新的对象。

class Egg{

    static Egg e;

    int i;
    Egg(int ii):i(ii){}
    Egg(const Egg&);// prevent copy-construction

public:

    static Egg* instance(){return &e};

    int val() const{ return i; }

};

Egg Egg::e(47);

int main(){

    // Egg x(1); //Error
     cout<<Egg::instance()->val()<<endl;
    //~
}



2、控制连接。

一般情况下,文件作用域内的所有名字(即不嵌套在类或者函数中的名字)对程序中的所有翻译单元来说都是可见的,也即是外部的(extern)。全局变量和普通函数都是外部连接。

若只想让一个变量在文件范围内是可见的,而不与外部的标识符冲突,可以声明为 static 对象或函数,这些名字是内部连接。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值