静态关键字Static
1.引出
先看如下代码:
*/
#if 0
//普通成员变量是本类某个对象独有的,类作用域,不能实现共享,外界修改不了(比较安全)
class Student
{
public:
Student(int num = 0, const char* name = "", char sex = 'm') :m_count(0), m_num(num), m_sex(sex)
{
m_name = new char[strlen(name) + 1];
strcpy_s(m_name, strlen(name) + 1, name);
m_count++;
}
~Student()
{
if (m_name != NULL)
{
delete[]m_name;
m_name = NULL;
}
}
void Print()
{
cout << "总数:" << m_count << endl;
}
private:
int m_num;
char* m_name;
char m_sex;
int m_count;
};
void main()
{
Student s(1001, "张三", 'm');
Student s1(1003, "李四", 'm');
Student s2(2005, "小红", 'f');
s.Print();
s2.Print();
s1.Print();
}
我们想实现输出到场人数,可是输出结果却是:
因为此时的m_count分别是s.m_count,s1.m_count,s2.m_count,普通成员变量是本类某个对象独有的,如果想让m_count实现共享,有两种方法:
1.将m_count设定为全局变量;
缺点:全局变量可以实现对象的共享,但是没有权限的限制,导致其他的函数或者对象可以无限制修改,则会出现问题(不安全)
2.使用static关键词
2.Static 静态属性
1.类中声明的静态变量是不会占用空间的
class A
{
int m_a;
char m_b;
static int m_c;
}; //引用性声明
正常来说应该是12个字节,但是m_c是静态,所以只有8个字节
总结:
同全局变量相比,使用静态数据成员有两个优势 :
1 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其他全局名字冲突的可能性 .
2 可以实现信息隐藏,静态成员可以是 private 成员,而全局变量不能
2.Static修饰的函数
例如:
class Student
{
private:
int m_num;
char* m_name;
char m_sex;
static int m_count;
static void Show()
{
cout << "Show" << endl;
cout << m_num << " " << m_name << " " << m_sex << " " << "总数:" << m_count << endl;
}
};//error
如图所示代码是会报错的,因为Static修饰的Show()函数是不会有this指针的,所以没有办法认清m_num,m_name,m_sex是哪个对象的数据成员,而m_count被Static修饰,所以没有报错。
解决方法:
在Show()函数传参时,传过来一个类的引用对象,例如:
static void Show(Student& s)
{
cout << "Show" << endl;
cout << s.m_num << " " << s.m_name << " " << s.m_sex << " " << "总数:" << m_count << endl;
}
总结:
1设计静态数据成员目的是信息共享,和信息交流.
2.类的静态数据成员为所有类对象所共享,不属于某个具体的实例。
3.类的静态数据成员必须在类外定义,定义时不添加static关键字,不能在构造函数的初始化列表中创
建。
4.类的静态数据成员类型是int,short, char ,long long ,并且是const , 可以在类中直接初始化,也可以在
类外初始化.
5.在类的成员函数中使用静态数据成员,静态数据成员之前没有this.
6.当类的静态数据成员为公有时,可以在外部函数使用: 类名::静态数据成员名 或 对象.静态数据成员名.
可以在类体中定义自身的静态类型对象.