**************************C++中的static的用法********************************
*******************************************************************************
C++primer里面讲过:static成员它不像普通的数据成员,static数据成员独立于该类的任意对象而存在,每个static数据成员是与类关联的对象,并不与该类的对象相关联!这句话可能比较拗口,其实可以这么理解:每个static数据成员可以看成是类的一个对象,而不与该类定义的对象有任何关系!下面我们就来具体看看类中的static数据成员!
一、static变量 修饰数据成员
1、static变量 ( 修饰数据成员) 的例子:
#include<iostream>
#include<string>
using namespace std;
class Person
{
private:
string name;
static int age; //static数据成员age
public:
Person(const string &nm):name(nm){};
void Print();
};
int Person::age = 20; //对static数据成员进行初始化
void Person::Print(){
cout<<name<<" is "<<age<<endl;
}
int main(int argc,char **argv)
{
Person person("tom");
person.Print();
Person person2("nike");
person2.Print();
person.Print();
return 0;
}
解释一哈:
对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当作是类的成员。无论是这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷贝,由改类型的所有对象共享访问。也就是说,静态数据成员是该类的所有对象所共有的。对该类的多个对象来说,静态数据成员只分配一次内存,供所有对象共用。所以,静态数据成员的值对每个对象都是一样的,他的值可以更新。
对C++中静态数据成员的了解:
静态数据成员初始化格式:<数据类型><类名>::<静态数据成员名>=<值>
存储:static数据成员是存储在程序的静态存储区,并不是在栈空间上的。(一般程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。)
初始化:在类中不能对static数据成员进行初始化,要初始化的话必须在类外进行定义! static数据成员不是通过类构造函数进行初始化的!如上面的代码所示:在类外定义int Persion::age = 20;这里前面就不加static 了。
如何访问static数据成员:我们可以通过作用域操作符从类直接调用static数据成员;或者通过对象;或者通过引用;或者指向改类类型对象的指针间接调用(这种情况下static数据成员是public的访问权限,如果定义在private访问权限下是不行的)。
注意:如果类中有多个static数据成员,static数据成员初始化的次序是按照static数据成员在类中的声明次序进行初始化的,初始化后,就可以使用static数据成员了。
总结:在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝。
2、const static数据成员 的例子:
像上面说的,类的static成员,智能在类的定义体外进行初始化。const int 类型的static成员便可以在类定义体内部进行初始化。记住,一定只能是const int型的,换成const string ,double都不行的。
#include<iostream>
#include<string>
using namespace std;
class Person
{
private:
string name;
static const int age = 20;//在类的定义体内进行初始化
static string address;
public:
Person(const string&nm):name(nm){}
static string Address()
{
return address;
}
void Print()
{
cout<<name<<" is "<<age;
}
};
string Person::address = "XiangGang"; //在类的定义体外进行初始化
int main()
{
Person person("tom");
person.Print();
cout<<" and live in "<<person.Address();
cout<<endl;
return 0;
}
解释一哈:
只有age才能在类定义体内进行初始化,address是不行的。
3、****** 的例子:
static数据成员的类型可以是该成员所属的类的类型,非static数据成员被限定为其自生类的指针或引用。
class Person
{
private:
string name;
static const int age = 20;//在类的定义体内进行初始化
static string address;
static Person person1;
Person *person2;
Person person3;
public:
Person(const string&nm):name(nm){}
static string Address()
{
return address;
}
void Print()
{
cout<<name<<" is "<<age;
}
};
解释一哈:
如果没有定义person3,则能顺利通过编译,但是加上person3就不能通过编译了。
二、static变量 修饰成员函数:
#include<iostream>
using namespace std;
class Myclass
{
public:
Myclass(int a,int b,int c);
static void GetSum();//声明静态成员函数
private:
int a,b,c;
static int Sum;//声明静态数据成员
};
int Myclass::Sum = 0;//定义并初始化静态数据成员
Myclass::Myclass(int a,int b,int c)
{
this->a = a;
this->b = b;
this->c = c;
Sum += a+b+c;//非静态成员函数可以访问静态数据成员
}
void Myclass::GetSum() //静态成员函数的实现
{
// cout<<a<<endl; //error a是非静态数据成员
cout<<"Sum = "<<Sum<<endl;
}
int main()
{
Myclass M(1,2,3);
M.GetSum();
Myclass N(4,5,6);
N.GetSum();
Myclass::GetSum();
}
解释一哈:
非静态成员函数可以访问,静态数据成员与普通数据成员;静态成员函数只能访问,静态数据成员,不能访问非静态数据成员。
说完了static成员后,我们再来看看static成员函数,static成员是类的组成部分并不是任何对象的组成部分,因此,static成员函数没有this指针。我们知道,一般而言,类中的成员函数具有一个附加的隐含实参,即指向该类对象的一个指针。这个隐含实参命名为this。因为static成员函数不是任何对象的组成部分,所以static成员函数就没有this形参了。由于成员函数声明为const说明该成员函数不会修改该成员函数所属的对象,所以static成员函数不能声明为const。为什么呢?因为static成员函数不是任何对象的组成部分。static成员函数可以直接访问所属类的static成员,但是不能直接使用非static成员函数!也不能访问static const 类型的成员!在上面的代码中static string Address()函数中如果是return name或者是return age都不行!
注意:
*出现在类体外的函数是不能指定关键字static的;
*静态成员之间可以相互访问, 包括静态成员函数访问静态数据成员和访问静态成员函数;
*非静态成员函数可以任意访问静态成员函数和静态数据成员;
*静态成员函数不能访问非静态成员函数和非经验数据成员;
*因为没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度会有少许的增长;
*调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式:
<类名>::<静态成员函数名>(<参数表>)调用类的静态成员函数。
总结:在类中的static成员函数属于整个类所拥有,这个函数不接受this指针,因而只能访问类的static成员变量。
参考的网址:
1》C++类中的static数据成员、static成员函数:https://www.cnblogs.com/yyxt/p/4802688.html
2》C++中static的完全解析:https://blog.csdn.net/jsjwql/article/details/1788286