static

c/c++共有

1):修饰全局变量时,表明一个全局变量只对定义在同一文件中的函数可见。

2):修饰局部变量时,表明该变量的值不会因为函数终止而丢失。

3):修饰函数时,表明该函数只在同一文件中调用。

c++独有:

4):修饰类的数据成员,表明对该类所有对象这个数据成员都只有一个实例。即该实例归 所有对象共有。

5):用static修饰不访问非静态数据成员的类成员函数。这意味着一个静态成员函数只能访问它的参数、类的静态数据成员和全局变量

 

1.在头文件把一个变量申明为static变量,那么引用该头文件的源文件能够访问到该变量吗。

答:可以。声明static变量一般是为了在本cpp文件中的static变量不能被其他的cpp文件引用,但是对于头文件,因为cpp文件中包含了头文件,故相当于该static变量在本cpp文件中也可以被见到。当多个cpp文件包含该头文件中,这个static变量将在各个cpp文件中将是独立的,彼此修改不会对相互有影响。

如果在一个头文件中声明:
static int g_vaule = 0;
那么会为每个包含该头文件的cpp都创建一个全局变量,但他们都是独立的;所以也不建议这样的写法,一样不明确需要怎样使用这个变量,因为只是创建了一组同名而不同作用域的变量。

补充:所有cpp可共享的全局变量

声明所有cpp可共享的全局变量,在头文件里声明为extern的:
extern int g_; // 注意,不要初始化值!
然后在其中任何一个包含该头文件的cpp中初始化(一次)就好:
int g_ = 0; // 初始化一样不要extern修饰,因为extern也是声明性关键字;
然后所有包含该头文件的cpp文件都可以用g_这个名字访问相同的一个变量;

 

2.为什么静态成员函数不能申明为const

答:这是C++的规则,const修饰符用于表示函数不能修改成员变量的值,该函数必须是含有this指针的类成员函数,函数调用方式为thiscall,而类中的static函数本质上是全局函数,调用规约是__cdecl或__stdcall,不能用const来修饰它。<span style="line-height:26px">一个静态成员函数访问的值是其参数、静态数据成员和全局变量,而这些数据都不是对象状态的一部分。而对成员函数中使用关键字const是表明:函数不会修改该函数访问的目标对象的数据成员。既然一个静态成员函数根本不访问非静态数据成员,那么就没必要使用const了

3.为什么不能在类的内部定义以及初始化static成员变量,而必须要放到类的外部定义

答:因为静态成员属于整个类,而不属于某个对象,如果在类内初始化,会导致每个对象都包含该静态成员,这是矛盾的。

在C++中,类的静态成员(static member)必须在类内声明,在类外初始化,像下面这样

class A
{  
private:
    static int count ; // 类内声明
};

int A::count = 0 ; // 类外初始化,不必再加static关键字

 

4.static关键字为什么只能出现在类内部的声明语句中,而不能重复出现在类外的定义中。

答:如果类外定义函数时在函数名前加了static,因为作用域的限制,就只能在当前cpp里用,类本来就是为了给程序里各种地方用的,其他地方使用类是包含类的头文件,而无法包含类的源文件。

 

5.为什么常量静态成员数据的初始化可以放在类内

(注意:只有静态常量整型数据成员才可以在类中初始化)

答:是否可以这样理解: static数据成员在类外定义和初始化是为了保证只被定义和初始化一次,这样编译器就不必考虑类的函数里面第一个对static变量的’=’操作是赋值还是初始化了。 static const int可以在类里面初始化,是因为它既然是const的,那程序就不会再去试图初始化了。

补充:静态常量整型数据成员类内初始化
能在类中初始化的成员只有一种,那就是静态常量成员。

复制代码
//这样不行 
class A { 
private: 
    static int count = 0; // 静态成员不能在类内初始化 
};
 
//这样也不行 
class A { 
private: 
    const int count = 0; // 常量成员也不能在类内初始化 
};
 
//但是这样可以 
class A { 
private: 
    static const int count = 0; // 静态整型常量成员可以在类内初始化,但是 static const float count就不行了,已验证的确不行,22年11月17号
};
复制代码

 

6.为什么静态成员函数只能访问静态成员变量。

答:1.静态成员函数只属于类本身,随着类的加载而存在,不属于任何对象,是独立存在的

2.非静态成员当且仅当实例化对象之后才存在,静态成员函数产生在前,非静态成员函数产生在后,故不能访问

3.内部访问静态成员用self::,而访问非静态成员要用this指针,静态成员函数没有this指针,故不能访问。

补充:静态成员访问方式

无论是静态成员变量还是静态成员函数,都是三种访问方式
1.通过对象访问
2.通过对象指针访问
3.通过类名访问

复制代码
class Car {
public:
    static int ms_count;
};
int Car::ms_count = 0;
---------------------------------------------
//通过对象访问
Car car0;
car0.ms_count = 100;
//通过对象指针访问
Car* p = new Car();
p->ms_count = 200;
//通过类名访问
Car::ms_count = 300;
复制代码

补充:类成员分配内存时机

类的静态成员(数据成员和函数成员)为类本身所有,在类加载的时候就会分配内存,可以通过类名直接访问;非静态成员(数据成员和函数成员)属于类的实例所有,所以只有在创建类的实例的时候才会分配内存,并通过实例去访问。

注意:类的静态数据成员是静态存储,它是静态生存周期,必须进行初始化。

注意:静态数据成员的初始化在类体外进行,前面不加static以免与一般静态变量或者对象混淆。

 

7.静态成员函数与非静态成员函数的区别

答:根本区别:静态成员函数不存在this指针,不能访问非静态成员变量。

 

8.为什么要用得静态成员变量和静态成员函数

答:为了实现共享。因为静态成员函数和静态成员变量属于类,不属于类的实体,这样可以被多个对象所共享

 

9.静态成员的作用、优点

答:静态成员函数主要为了调用方便,不需要生成对象就能调用。

class X
{
public:
    void MethodA();
    static void MethodB();
}

MethodB可以直接调用,X::MethodB();
MethodA必须先生成类对象才能调用,X x; x.MethodA();

posted @   ImreW  阅读(53)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示