C++静态成员

static

        static这个关键字在c中有两个完全不相干的两种语义,在函数局部用来修饰局部变量,函数前面用来将函数的作用域限定在本文件中。为了尽可能的减少关键字,所以c++又给static定义了第三种完全不相干的语法,在类中用来修饰静态成员。

        static用在成员变量,那么就是静态成员变量;static用在成员函数,那么就是静态成员方法;

static成员实例化

        经过static修饰后的成员属于类本身而不属于对象,在定义对象的时候不会去实例化静态成员变量,所以需要对其进行独立定义,示例如下,静态成员函数则不需要单独初始化,因为函数实体编写在外部,本身就是一种初始化。

class person       //定义一个person类
{
   public:
   static  int a;  //声明一个静态成员变量a
};
int person::a=23;  //定义静态成员变量并初始化

        静态数据成员不能在类中初始化,因为类型定义只是定义了一个模板。也不能在构造函数中初始化,因为静态变量是多个对象共享的,假如构造函数能初始化,那么类每创建一个对象都会改变静态成员的值,就乱套了,当然也不能用初始化列表来初始化,初始化时如果不赋初值,默认等于0。

静态成员变量访问

        static成员既然是在类中,自然就遵循类的权限管理。静态成员可以单独使用“域名::成员名”来访问,也可以通过对象访问,示例如下,在定义了多个对象时,其多个对象都可以访问被声明的静态成员变量或方法,且访问的是同一个实体,被多个对象“共享”。

person::a=23;                          //单独访问
person p1,p2;                //定义2个对象
cout<<"p1.a = "<<p1.a<<endl; //基于p1访问a
cout<<"p2.a = "<<p2.a<<endl; //基于p2操作a

        想要静态修饰成员函数,只能在类中添加static,不能在外部实体函数添加,因为外部实体函数前添加static与文件内作用域功能的static冲突。

普通成员与静态成员互掉

        普通成员函数可以调用静态成员变量,调用方法有如下三种,推荐使用第二种,因为第二种从语法上一看就知道是静态成员。

p1.a=23;              //通过对象访问
person::a=23;       //通过类名访问
this->a=23;          //通过对象指针访问

        静态方法只能访问静态成员和方法,不能访问任何非静态的东西。如果要非要访问可以使用函数传参方式来实现。示例如下:

p1.print(p1.b);
void person::print(int aa)
{
       cout << "a = " <<aa <<endl;
}

从内存角度对比

        普通成员与对象绑定,随对象的建立而建立,随对象的消亡而释放,类似于局部变量或malloc堆内存。

        静态成员在链接时分配地址,程序加载时被建立,程序结束时消亡,等同于全局变量。静态成员函数也遵循该规则,类似于全局函数。

        静态成员变量在对象中不占用存储空间,只是一个申明,他的内存空间与全局变量在一个区域。

静态成员的用途

        静态成员是与类相关的,是一种类的行为,而不是与该类实例的对象相关,例如我们抽象一个类来描述一个学生,一个对象代表一个学生,而对所有学生的统一描述如学生人数、平均成绩等,放在对象中显然不合适,适合用静态成员变量来记录,对静态成员进行操作的函数就适用静态函数来描述,实现代码如下示例:

/*
*每个学生用一个对象来表达,使用静态成员来实现学生人数统计
*/
#include<iostream>
using namespace std;
class student
{
       public:
              static int num;           //学生人数,静态成员声明
              static void print(void);  //打印人数,静态成员声明
              student(string n,int a);  //类的构造函数
              ~student();               //析构
       private:
              string name;              //姓名
              int age;                  //年龄
};

int student::num;                       //静态成员变量定义
void student::print(void)               //函数实体
{ 
       cout << "student num: " << student::num << endl;
}

student::student(string n,int a)       //构造函数
{
       name = n;
       age =a;
       student::num++;
}

student::~student()                    //析构函数
{
       student::num--;
}

int main(void)
{
       student s1("hanmei",18);        //实例化对象
       student s2("lilei",17);         //实例化对象
       student::print();               //打印数量
       return 0;
}

静态成员与面向对象

        静态成员仍然在class内,仍可通过对象调用,表面上是遵守了面向对象的规则。实际上静态成员一定程度的破坏了面向对象,即使没有对象仍然可以单独访问到静态成员。

        静态成员变量其实就是将全局变量封装到了类中,以方便访问。

        静态成员和非静态成员完全不同,两个唯一的共同点就是都被包含在了同一个类中。

静态类

什么是静态类

        class中所有的成员都是静态成员,那么这个类就成了一个静态类,这些静态类全部都需要进行外部定义,类中其实是空的,所以静态类不能实例化对象,没有对象,class的很多操作都不能有,例如,不能被继承不能有protected不能指定任何接口实现,不能有普通构造函数,但是可以有静态构造函数,来分配初始值或设置某个静态状态。

密封(sealed

        静态类不能被继承,这一特性间接的实现了对类的密封(sealed,在java等高级语言中,源支持密封,虽然c++不支持,但是可以使用静态类来间接实现。由于类都有构造函数,有了构造函数,被调用时就有可能去实例化对象,语法规定又不能没有构造函数,解决方法就是将构造写在private下。

小结

        静态类实际上使用得比较少,所以没有展开讲。而静态成员在c++中略显尴尬,即使没有静态成员,使用全局变量一样可以完成功能,这跟静态局部变量有些像,静态局部变量其实也可以使用全局变量来替代,只不过静态局部变量的作用域不同,只能在函数内部访问,但是又具有全局变量的特性。静态成员也是这各道理,具有全局变量的特性,但是作用域又只能基于类访问,将全局变量与。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值