类的静态成员

来源:互联网 发布:php判断是否点击submit 编辑:程序博客网 时间:2024/05/16 02:14

开门见山--->本篇博客我们主要讲:类的静态成员及其相关

由于之前学习c语言的时候大家对static关键字想必并不陌生,而本篇博客我们依旧需要用到static,只不过是更深入的运用。按例,首先还是以一段简单的代码来回顾一下:

#include<iostream>using namespace std;#include<stdlib.h>int a = 0;static int b = 0;//链接属性void f(){static int c = 2;}int main(){cout << b << c << endl;return 0;}

这里定义了3个变量:其中b和c都是静态成员变量,它们的作用域不一样(c的作用域只是在f()函数内),但是生命周期一样。所以在main函数中访问c就出现了问题

下来我们再设想这样一种情况定义一个日期类,怎样才能统计到所创建的对象个数

class Date{public:Date(int year):_year(year){++_cout;}Date(const Date&d){++_cout;}private:int _year;static int _cout;};int main(){Date d(2016);return 0;}
但是这里会出现链接错误:


这里要注意:类的静态成员变量不能在类中进行初始化,而是要在类外面进行初始化,即

int Date::_cout = 0;
为什么不在类的成员函数中初始化呢?这是因为:静态成员变量不是属于某个对象所拥有的,因为它的生命周期是全局都存在的;如果属于某个对象,则就无法统计个数(因为每一次调用构造函数,拷贝构造都在创建对象),它是属于日期类所有对象所共享的。

这里证明一下:

cout << sizeof(Date) << endl;
得出结果是4,也就验证了我们的猜想:d是一个局部对象,在栈帧里面,而_cout是在静态区的。

由于_cout是私有的,那么要想访问到它,我们就必须通过成员函数进行访问:

class Date{public:Date(int year):_year(year){++_cout;}Date(const Date&d){++_cout;}static void PrintCount(){cout << _cout << endl;//cout << _year << endl;}private:int _year;static int _cout;};int Date::_cout = 0;int main(){Date d1(2016);Date d2(d1);Date d3(11);d1.PrintCount();return 0;}

可见通过调用“对象.成员函数”的方式可以成功访问到_cout,但是这里还有一个问题:前面我们已经分析过,_cout不是某个对象所拥有的,而是所有对象共享的;这样的话即使不创建对象,它也应该是存在的,可是当我们试验时,却出现了问题

int main(){Date d1(2016);Date d2(d1);Date d3(11);PrintCount();return 0;}

那么怎么来成功访问到_cout呢?这里就可以把PrintCout()函数定义成静态的

//在类中把PrintCount()定义为静态成员函数class Date{public:static void PrintCount(){cout << _cout << endl;//cout << _year << endl;}};
//PrintCount()的调用int main(){Date d1(2016);Date d2(d1);Date d3(11);Date::PrintCount();return 0;}
那静态成员函数和普通成员函数有什么区别呢?(这里还是以上面的代码为例,不过我们在静态成员函数中加上一句:访问私有成员_year)

static void PrintCount(){cout << _cout << endl;cout << _year << endl;}

会发现编译不通过,这里“非静态成员引用必须与特定对象相对”又是什么意思?

我们知道,之前,访问类中的私有成员时,我们都会通过成员函数来进行访问:在main函数中创建一个对象,再通过对象调用成员函数。无论创建几个对象,我们都可以通过这样的方法准确输出各个对象的私有成员不同值;仔细思考,其实对象调用成员函数访问成员变量就是通过this指针进行访问的,而this指针通过是对象的地址传过来的。而静态成员变量是属于整个类所拥有,是所有对象所共享的,它是全局的。同理,静态成员函数也一样,它是整个类共享的,不是特定地属于某一个对象的;以前我们访问成员变量都是通过成员函数传递this指针进行访问,这里由于是“静态成员函数”,所以不存在this指针,所以编译器就无法确定这里的_year究竟访问的是哪个对象的_year

综上:总结--->静态成员函数有一个显著的特征:没有this指针,所以可以使用类型: : 作用域访问符直接调用静态成员函数

问题:
1 .   静态成员函数可以访问非静态的成员吗?

答:不可以,非静态的成员一定是属于某个类的,必须通过this指针才能访问,静态成员函数没有this指针
2 .   非静态的成员函数可以访问静态成员吗?

答:可以,态成员不仅属于某个类,也是大家所共享的,没有this指针都可以访问,有this指针就更可以了










0 0
原创粉丝点击