对C++ static作用——修饰 数据成员(改变为静态数据成员)、 成员函数(改变为静态成员函数)

**************************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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值