静态成员变量(static)
static存在静态区(全局区)
我们可以使用static关键字来把类成员定义为静态的。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本。
static成员变量和普通static变量一样,都在内存分区中的全局数据区分配内存,到程序结束时才释放。这就意味着,static 成员变量不随对象的创建而分配内存,也不随对象的销毁而释放内存。而普通成员变量在对象创建时分配内存,在对象销毁时释放内存。
普通成员变量在类内初始化,静态成员变量在类外初始化
静态变量初始化时可以赋初值,也可以不赋值。如果不赋值,那么会被默认初始化为0。全局数据区的变量都有默认的初始值0,而动态数据区(堆区、栈区)变量的默认值是不确定的,系统会给这个变量自动赋一个随机的值。
静态变量只在当前文件内生效,不同的文件中命名相同名字的静态变量不会发生重定义。
静态成员需要赋值
●静态成员变量不属于对象,属于整个类所有,所有对象共享同一个类的静态成员变量
●静态成员变量不会影响类的大小
●静态成员变量需要在类外初始化(必须初始化,可以不赋值)
●可以通过类名直接访问公有静态成员变量
●可以通过对象名访问公有静态成员变量
●静态成员变量在程序内部位于全局数据区(静态区)
●静态成员变量的生命期不依赖于任何对象,与程序的生命周期一致
●静态成员变量不会被继承,父类和子类共享静态成员变量
#include<iostream>
using namespace std;
class A {
public:
static int a;//静态成员变量必须在类外初始化
int b;
A()
{
a++; ///所有对象共享—个静态成员变量,用a表示创建了多少个对象
cout << a << endl;
}
};
int A::a = 0;//在类外初始化静态成员变量,因为静态成员变量属于类,不属于某一个对象,不需要创建对象也能调用。可以不赋值
int main()
{
//A::a=1; 静态成员变量是属于整个类的,可以通过类名+::直接调用
A c1;
A c2;
A c3;
c1.a = 5;//可以通过对象调用静态成员变量
}
#include<iostream>
using namespace std;
class A {
public:
const static int a = 2;//const类型必须初始化
int b;
};
int main()
{
A a;
cout << a.a << endl;//2
}
#include<iostream>
using namespace std;
class A {
public:
//类所有对象共享同一个静态成员变量
static int a;
int b;
};
int A::a = 1;
class B : public A//共享的
{
};
int main()
{
A::a = 3;
cout << B::a << endl;//3
}
静态成员函数
●定义静态成员函数,直接使用static关键字修饰即可,静态成员函数属于整个类所有,没有this指针
●静态成员函数只能直接访问静态成员变量和静态成员函数(因为没有this指针,因为访问普通的成员变量和成员函数前面都隐含了this)和类外部的其它函数
●可以通过类名直接访问类的公有静态成员函数
●可以通过对象名访问类的公有静态成员函数
<!--this怎么来的? 答:通过隐含的参数过来的-->
<!--函数的类型是返回值类型-->
*<!--不可以调用普通的静态成员变量和静态成员函数-->*
<!--不用对象也会有静态成员函数,this指针是指向对象的,this就不需要了-->
<!--调用成员变量时,前面都有一个默认的this-->
public:
int a;
A()
{
a++;//前面都有一个默认的this
}
static void fun()//静态成员函数不能访问int a 因为没有this
{
cout<< a << emdl;
}
#include<iostream>
using namespace std;
class A
{
public:
int c;
static int b;
void s()
{
c = 1;//this->c =1;
}
static void sta_d(){}
static int sta_fun(int a)
{
sta_d();//静态成员函数可以调用静态成员函数
b = 2; //静态成员函数可以调用静态成员变量
//s(); //error s()相当于this->s(), 但是静态成员函数里面没有this,因为他属于整个类,不属于具体某个对象
//c = 3; //error因为非静态成员变量需要创建对象的时候才能分配空间,然而静态成员函数不需要创建对象就已经存在了,所以有冲突。
cout << "静态成员函数" << endl;
return 0;
}
};
int A::b = 1;
int main()
{
A::sta_fun(1); //通过类名+作用域直接访问类的公有静态成员函数
A a;
a.sta_fun(1); //通过对象直接访问类的公有静态成员函数
A b();//这里没有创建对象,不会调用类的默认构造函数,编译器会认为他是一个函数声明,A是返回值b是函数名()是函数参数。
A d; //调用默认构造函数
}
局部静态变量static
●在局部变量前加上“static”关键字,就成了静态局部变量。
●静态局部变量存放在内存的全局数据区。
●函数结束时,静态局部变量不会消失,每次该函数调用 时,也不会为其重新分配空间。它始终驻留在全局数据区,直到程序运行结束。静态局部变量的初始化与全局变量类似.
●如果不为其显式初始化,则C++自动为其 初始化为0。
●静态局部变量与全局变量共享全局数据区,但静态局部变量只在定义它的函数中可见。静态局部变量与局部变量在存储位置上不同,使得其存在的时限也不同,导致对这两者操作 的运行结果也不同。
#include <iostream>
using namespace std;
int n = 1; //全局变量
void func()
{
static int a = 2; // 静态局部变量
int b = 5; // 局部变量
a += 2;
n += 12;
b += 5;
cout << "a:" << a
<< " b:" << b
<< " n:" << n << endl;
}
void main()
{
static int a; // 静态局部变量
int b = -10; // 局部变量
cout << "a:" << a
<< " b:" << b
<< " n:" << n << endl;
b += 4;
func();
cout << "a:" << a
<< " b:" << b
<< " n:" << n << endl;
n += 10;
func();
system("pause");
}