什么是静态成员(静态数据成员和静态函数成员)

什么是静态成员(静态数据成员和静态函数成员),第1张

一:静态成员:


c++类中声明成员时, 加上static关键字声明的成员叫静态成员。


跟平时声明成员时一样,只不过是在前面多加了一个static
静态成员分为:

静态数据成员静态函数成员(因为类的成员本身就分为两类,属性和行为,也就是数据和函数)


二:静态数据成员:


一:类中定义
二:类外初始化
为什么要这样类外初始化呢?
代码解释:
 

#include
using namespace std;

class ClassName
{
public:
    ClassName();
    static int val;//现在类中声明一个静态数据成员val,只需要给在类型前面加上static就完事了
};
ClassName::ClassName()
{

}
int main()
{
    ClassName  obj;//创建对象
    obj.val = 0;
    cout << "obj.val=" << obj.val << endl;
    return 0;
}


但是如果这样写的话,编译器就会报错,找不到val,所以这样是错的

正确的静态数据成员定义和初始化的代码格式如下:

class ClassName
{
public:
    static Type date;//静态数据成员定义

};
Type ClassName::date = val;//静态数据成员类外初始化,可以这样理解:静态数据成员只能在类内定义,但是如果要进行初始化的时候
//就必须这样在类外初始化,像这样用作用符把要初始化的数据成员,声明一下它是属于类的,用类名加以限定
所以代码变成这样就实现了静态数据成员的定义和初始化以及输出
#include
using namespace std;

class ClassName
{
public:
    ClassName();
    static int val;//现在类中声明一个静态数据成员val,只需要给在类型前面加上static就完事了
};
int ClassName::val;//静态数据成员初始化
ClassName::ClassName()
{

}
int main()
{
    ClassName  obj;//创建对象
    cout << "obj.val=" << obj.val << endl;//
    return 0;
}
这样就能很好的对静态数据成员定义和初始化了

定义静态数据成员其实和静态变量一样。

只不过在C++ 中是数据成员而已
有区别的也就是
静态数据成员必须要类内定义,类外初始化,而且只能初始化,不能赋值  int ClassName::val = 0;


三:静态数据成员的特点:


一:所有对象都共享该数据成员,只有一份内存
二:必须要在类外进行初始化

首先只有一个,那么就不可能属于任何一个对象,因为如果属于了,那么别人就用不了了,比如说太阳,这里的太阳就可以指,静态数据成员,所有人都能照射到,所有对象都可以访问到,但是如果太阳被某人藏起来了,那么别人就照射不到,访问不到了,那样就麻烦了。


所以静态数据成员应该是属于类的,类是对象的概括总结,也可以理解成是共享单车


为什么只能是在类外初始化,类内定义,连饿构造函数都不行,那么有人就问了,构造函数难道不是用来赋初值的嘛,那是因为每次创建对象的
时候都调用一次构造函数,那么调用一次,数据可能就会被修改一次,而静态数据成员是共享一份内存的,如果随意改变了,那么可能就会出现
问题了

为什么不能用对象去赋值初始化呢,因为静态数据成员说白了还是静态变量,既然是静态变量,那么就属于静态全局区,全局区的变量,随程序生,随程序死,那么对象的话,总有对象不是在静态全局区的,随程序生,随程序死的,那么由于生命周期的不同,所以就容易出现问题
自然就不能这么使用了

四:访问静态数据成员


一:可以在类中重新赋值,可以被普通函数访问
二:如果是公有属性,可以在类外被对象访问,或者通过类名访问(类名+作用符+数据成员名) 比如:ClassName::val;
要注意的是:类名访问,肯定是从类外访问,那么类外访问的话,就要求静态数据成员是公有属性
可以用类名访问这一点也说明:静态数据成员肯定不是属于对象的,如果是属于对象,那么又怎么能用类名去访问呢

五:静态函数成员,如何定义成员函数


一:直接在类中定义
二:在类中声明,在类外定义
代码举例:

class ClassName
{
public:
    static Type fun(){}//在类中定义
    static Type fun2();//类中声明
};
Type ClassName::fun2(){}//在类外定义

在类外定义的时候不需要再加上static 如:static void ClassName::test_fun1(),这样写是不对的,正确的类外定义应该是
void ClassName::test_fun1()

六:静态数据成员的特点、


一:不属于对象,而是属于类的
二:不能 *** 作类中的普通成员和普通成员函数
原因是因为普通数据成员是在类中声明的,但是这些普通的数据成员初始化是在创建对象的时候通过构造函数去初始化的,那么它的生命周期和静态的就不太一样,但反是static修饰的,就是生命周期比较长,随程序生随程序死,另外像这些静态函数由于是static修饰的,那么在你去访问这些东西的时候,你可以像以前一样通过类去点出来,如果是公有的话,但是还可以通过类名去访问:ClassName::test_fun1()
那么这样的去调用的时候就会出现一个问题,我们以前的函数是通过对象去调用的,不管是点还是用指针指,总之都是用对象去调用的,那么必须要有一个调用函数的对象,那么就会存在一个this指针会指向调用函数的对象,但是在这里是直接通过类名+作用符去访问当前静态成员函数的,这个过程中不存在对象的事情,也就是说虽然调用了静态函数,不是用对象调的,如果存在this指针,那么this指针指向谁呢,没有对象去调用它,如果有this指针,它没地方指,所以我们在静态函数中写一个this是不对的,
静态函数中是不存在this指针的,因为可以通过类名直接去访问函数,那么过程中间不存在对象,this指针就没得去指向了,为了避免这种情况的发生,索性就静态函数中就不要this指针了,如果通过对象去调用,虽然可以正确调到,但是this指针也没了
另外由于对象和静态的生命周期不同,可能会导致,有静态没对象,this指针就没得指,另外,虽然静态不能调用数据成员,但是普通函数可以调用,那么怎样避免调用的普通函数中调用了数据成员的情况呢?索性就一刀切,既不要访问数据成员也不访问函数


 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/673304.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-19
下一篇 2022-04-19

发表评论

登录后才能评论

评论列表(0条)

保存