精华内容
下载资源
问答
  • 下面小编就为大家带来一篇C++静态成员函数不能调用非静态成员变量(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 静态成员变量: 类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。同时,静态数据成员还具有以下特点...
  • 可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员..因为静态成员存在于内存,所以非静态成员可以直接访问类中静态的成员. 非...
  • 静态成员函数不能访问非静态成员,这是因为静态函数属于类而不是属于整个对象,静态函数中的 member可能都没有分配内存。静态成员函数没有隐含的this自变量。所以,它就无法访问自己类的非静态成员
  • 详解c++ 静态成员变量

    2020-12-17 00:17:53
    仔细琢磨静态成员变量,会发现其与C++的方式既相容也矛盾,具有特殊性。 先说相容的一面。·C/C++·有声明和定义的说法:声明给出签名,定义给出具体实现。对类型而言,声明不一定能知道其对象占用空间大小,但根据...
  • C++中静态成员函数与静态成员变量(static ) 这篇介绍了静态成员函数与静态成员变量,是我的读书笔记,我希望它够简短但又比较全面,起到复习的作用。如果有一些C++知识记不清楚了,它可以帮你很快回忆起来。 复习...
  • 静态成员变量和静态成员函数 class ClassA { int a; int b; static int c; //静态成员变量 static void xxx_fun() //静态成员函数 { ... } } 普通成员变量每个对象都有各自的一份,静态成员变量所有对象...
  • c++ 静态成员变量用static 关键字来声明,是整个类的数据成员,其存储不占用某个具体对象的空间,其存储在静态存储区。 c++ 静态成员函数用static 关键字来声明,用于处理静态成员变量,可以用类名来调用,也可以用...

    前言

    c++ 静态成员变量用static 关键字来声明,是整个类的数据成员,其存储不占用某个具体对象的空间,其存储在静态存储区
    c++ 静态成员函数用static 关键字来声明,用于处理静态成员变量,可以用类名来调用,也可以用对象名来调用。

    使用静态成员变量的目的:静态成员变量是整个类的数据成员,使用静态成员变量可以实现多个对象共享数据

    测试1:

    #include <iostream>
    using namespace std;
    
    class Point{
    public:
        Point(int xx,int yy):x(xx),y(yy){count++;}
        Point():Point(0,0){}
        Point(const Point &p);
        ~Point(){count--;}
        void show(){cout<<x<<" "<<y<<endl;}
        static void showcount();  //用static来声明静态成员函数
    private:
        int x,y;
        static int count; //用static来声明静态成员变量
    };
    
    int Point::count = 0;   //静态成员变量的定义,定义时前面不可以再有static, 且它必须要在类外面来初始化,不能在类内部初始化。静态成员变量在初始化时分配内存。
    
    void Point::showcount() {    //静态成员函数的定义,前面不可以再有static,可以在类内部定义,也可以在类外定义。此例为在类外面进行定义。
        cout<<"count="<<count<<endl;
    }
    
    Point::Point(const Point &p){  //复制构造函数
        x = p.x;
        y = p.y;
        count++;
    }
    
    Point fun(Point m){ 
        return m;
    }
    
    int main(){
        Point::showcount(); //用     类名::函数名      来调用静态成员函数
        Point a(1,2);
        a.show();
        a.showcount();//也可用    对象名.函数名   来调用静态成员函数
        Point b(a);
        b.show();
        b.showcount();
        Point c;
        c.show();
        c.showcount();
        Point d = fun(c);
        d.show();
        d.showcount();
        return 0;
    }
    

    运行结果:
    $ ./a.out
    count=0
    1 2
    count=1
    1 2
    count=2
    0 0
    count=3
    0 0
    count=4

    在这里插入图片描述
    如图,对象a占用8个字节(成员x,y的空间,count不在里面),对象a是局部对象,存放在栈上0x7fffffffdde0的位置处。
    在这里插入图片描述
    count存放在静态存储区的 0x555555756134,不存储在对象中。count属于整个类,不属于某一个具体的对象。
    静态成员函数也是一样,属于整个类,不属于某一个对象,所以静态成员函数可以用类名来调用,比如:Point::showcount() 。

    static 成员变量必须在类声明的外部初始化,具体形式为:

     type class::name = value;
    

    如本例:int Point::count = 0;
    静态成员变量在初始化时不能再加 static,但必须要有数据类型。

    static 成员变量的内存既不是在声明类时分配,也不是在创建对象时分配,而是在(类外)初始化时分配。没有在类外初始化的 static 成员变量不能使用,因为没分配空间。

    测试2:

    #include <iostream>
    #include <cmath>
    using namespace std;
    
    class Point{
    public:
        Point(int xx,int yy):x(xx),y(yy){count++;}
        Point():Point(0,0){}
        Point(const Point &p);
        ~Point(){count--;}
        void show(){cout<<x<<" "<<y<<endl;}
        static void showcount();
    public:
        static int count;   //此例为public属性
    private:
        int x,y;
    };
    
    int Point::count = 0;
     
    void Point::showcount() {
        cout<<"count="<<count<<endl;
    }
    
    Point::Point(const Point &p){
        x = p.x;
        y = p.y;
        count++;
    }
    int main(){
        Point::showcount();
        Point a(1,2);
        cout<<a.count<<endl;  //通过对象a来访问静态成员变量。若count不是public属性,不能用对象来访问,编译时就会报错
        Point::showcount();
        Point b(3,4);
        Point::showcount();
    
        return 0;
    }
    

    用GDB来查看静态成员变量的存储:
    在这里插入图片描述
    可以看到,当b中count变为2,a中count也变为2,即a和b中的count是共享的。查看a.count和b.count的地址,可以发现是同一个地址,即是同一个存储空间。且这个存储空间是全局存储区(静态存储区),不在对象a和对象b的栈(stack)存储区。
    此例中count是public,修改为protected和private,编译报错。

    protected:
        static int count;
    

    在这里插入图片描述

    private:
        static int count;
    

    在这里插入图片描述
    如上图,也就是说,想通过对象来访问静态成员变量,静态成员变量只能是public属性。这一点和对象去访问普通的成员变量一样。类外面,对象只能访问public成员变量,不能访问protected和private的成员变量。

    测试3:

    void Point::showcount() {
        cout<<"count="<<count<<endl;
        cout<<x<<endl; //新增,尝试在静态成员函数中去访问普通的成员变量,编译报错。
    }
    

    在这里插入图片描述
    也即是说,在静态成员函数中,不能去访问普通的成员变量。原因是没有this指针,不知道普通成员变量x放在哪里。
    原因分析:
    编译器在编译一个普通成员函数时,会隐式地增加一个形参 this,并把当前对象的地址赋值给 this,所以普通成员函数只能在创建对象之后通过对象来调用,因为它需要当前对象的地址。也即是有了对象,才有对象的this指针,没有对象,就无法调用普通成员函数。由于类没有this指针,所以不能用类名去调用普通成员函数,只能用实际的对象去调用普通成员函数

    而静态成员函数可以通过类来直接调用,编译器不会为它增加形参 this,它不需要当前对象的地址,所以不管有没有创建对象,都可以调用静态成员函数。因为静态成员函数要访问的是静态成员变量(存储在全局存储区,和this指针没毛关系)。
    由于静态成员函数没有 this 指针,不知道指向哪个对象,无法访问对象的成员变量,所以静态成员函数不能访问普通成员变量,只能访问静态成员变量

    总结:

    1. 一个类中可以有一个或多个静态成员变量,所有的对象都共享这些静态成员变量,都可以引用它。注意,是共享,共享,共享,也即是只会占同一份静态存储空间
    2. static 成员变量和普通 static 变量一样,都在内存分区中的全局数据区分配内存,到程序结束时才释放。这就意味着,static 成员变量不随对象的创建而分配内存,也不随对象的销毁而释放内存。而普通成员变量在对象创建时分配内存,在对象销毁时释放内存。根本原因是静态成员变量和对象的存储空间不同,是在不同的时期去分配的
    3. 静态成员变量必须初始化,而且只能在类体外进行。例如:
      int Point::count = 0;
      初始化时可以赋初值,也可以不赋值。如果不赋值,那么会被默认初始化为 0
      全局数据区的变量都有默认的初始值 0,而**动态数据区(堆区、栈区)**变量的默认值是不确定的,一般认为是垃圾值。
    4. 静态成员变量既可以通过对象名访问,也可以通过类名访问,但要遵循 private、protected 和 public 关键字的访问权限限制。
      当在类外面通过对象名访问时,静态成员变量属性必须是public,对于不同的对象时,访问的是同一份内存(本质是共享)。
    5. 静态成员函数在声明时要加 static,在定义时不能加 static 。静态成员函数只能访问静态成员变量,去访问普通成员变量,编译就报错。
    展开全文
  • 详细介绍了Java的静态成员变量、静态数据块、非静态成员变量和非静态成员变量等初始化顺序
  • 如果我们在成员变量前边加上static关键字,这个变量就成为静态成员变量,我们又把这种变量叫做“类变量”,因为这样的变量在这个类的所有对象里只有一个,这个类的所有对象“共享”同一个类变量。

    前两天朋友问我成员变量前边加static和不加static有什么区别,我把书给她看,书上是这么解释静态成员变量的:

    如果我们在成员变量前边加上static关键字,这个变量就成为静态成员变量,我们又把这种变量叫做“类变量”,因为这样的变量在这个类的所有对象里只有一个,这个类的所有对象“共享”同一个类变量。因此,一旦通过某个对象修改了静态变量的值,这个类的所有其他对象里面,这个静态变量的值就跟着变了。

    书上已经说得很清楚了,但为了方便理解,我写了两段简单的代码来帮助更好理解静态成员变量和非静态成员变量的区别。

    package test2;
    
    public class Test_Static {
    
     private static int i = 100;
    
     public int getI() {
      return i;
     }
     public void setI(int i) {
      this.i = i;
     }
     public void setI(int j, int k) {
      Test_Static m = new Test_Static();
      m.setI(j);
      i = m.getI() + k;
     }
     public static void main(String[] args) {
      Test_Static a = new Test_Static();
      a.setI(200);
      Test_Static b = new Test_Static();
      b.setI(b.getI(), 100);
      System.out.println(b.getI());
     }
    }

    控制台输出结果如下:
    在这里插入图片描述

    package test2;
    
    public class Test_NoStatic {
    
     private int i = 100;
    
     public int getI() {
      return i;
     }
     public void setI(int i) {
      this.i = i;
     }
     public void setI(int j, int k) {
      Test_NoStatic m = new Test_NoStatic();
         m.setI(j);
      i = m.getI() + k;
     }
     public static void main(String[] args) {
      Test_NoStatic a = new Test_NoStatic();
      a.setI(200);
      Test_NoStatic b = new Test_NoStatic();
      b.setI(b.getI(), 100);
      System.out.println(b.getI());
     }
    }

    控制台输出结果如下:
    在这里插入图片描述
    可以简单地说:成员变量 i 前边加了static,就可以理解为这个类里只有这一个变量,所以任意一个对象修改它的值它的值都会改变;成员变量 i 前边不加static,每个对象都有自己的 i ,修改自己的 i 不会改变另一个对象的 i 的值。

    展开全文
  • java中什么叫静态成员变量

    千次阅读 2021-02-26 08:24:08
    静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量,例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。...

    4baaa6d80bed31b166ff09822d7ced10.png

    静态变量的类型说明符是static。 静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量,例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。对于自动变量,它属于动态存储方式。 但是也可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式。

    由此看来, 一个变量可由static进行再说明,并改变其原有的存储方式。

    1. 静态局部变量

    在局部变量的说明前再加上static说明符就构成静态局部变量。

    例如:

    static int a,b;

    static float array[5]={1,2,3,4,5};

    静态局部变量属于静态存储方式,它具有以下特点:

    (1)静态局部变量在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。

    (2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。

    (3)允许对构造类静态局部量赋初值。若未赋以初值,则由系统自动赋以0值。

    (4)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。 根据静态局部变量的特点,可以看出它是一种生存期为整个源程序的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用,而且保存了前次被调用后留下的值。因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜

    —————————————————————————————————————————————————————————

    给读者一个简单直白的例子(区别静态局部变量和动态局部变量):

    ——————————************************************************************——————————

    int fun(int n)

    {

    static int f=1; /*请注意这行的修改*/ 这是 static 结果:

    f=f*n;

    return(f);

    }

    main()

    {

    int i;

    for(i=1;i<=5;i++)

    printf("%d!=%d\n",i,fun(i));

    }

    ——————————************************************************************——————————

    int fun(int n)

    {

    int f=1; /*请注意这行的修改*/ 结果是:

    这是auto 的结果

    f=f*n;

    return(f);

    }

    main()

    {

    int i;

    for(i=1;i<=5;i++)

    printf("%d!=%d\n",i,fun(i));

    }

    ————————————————————————————————————————————————————————————————

    2.静态全局变量

    全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。应予以注意。

    静态变量

    除范围之外,变量还有存活期,在这一期间变量能够保持它们的值。在应用程序的存活期内一直保持模块级变量和公用变量的值。但是,对于 Dim 声明的局部变量以及声明局部变量的过程,仅当过程在执行时这些局部变量才存在。通常,当一个过程执行完毕,它的局部变量的值就已经不存在,而且变量所占据的内存也被释放。当下一次执行该过程时,它的所有局部变量将重新初始化。

    但可将局部变量定义成静态的,从而保留变量的值。在过程内部用 Static 关键字声明一个或多个变量,其用法和 Dim 语句完全一样:

    Static Depth

    例如,下面的函数将存储在静态变量 Accumulate 中的以前的运营总值与一个新值相加,以计算运营总值。

    Function RunningTotal (num)

    Static ApplesSold

    ApplesSold = ApplesSold + num

    RunningTotal = ApplesSold

    End Function

    如果用 Dim 而不用 Static 声明 ApplesSold,则以前的累计值不会通过调用函数保留下来,函数只会简单地返回调用它的那个相同值。

    在模块的声明段声明 ApplesSold,并使它成为模块级变量,由此也会收到同样效果。但是,这种方法一旦改变变量的范围,过程就不再对变量排他性存取。由于其它过程也可以访问和改变变量的值,所以运营总值也许不可靠,代码将更难于维护。

    声明所有的局部变量为静态变量

    为了使过程中所有的局部变量为静态变量,可在过程头的起始处加上 Static 关键字。例如:

    Static Function RunningTotal (num)

    这就使过程中的所有局部变量都变为静态,无论它们是用 Static、Dim 或 Private 声明的还是隐式声明的。可以将 Static 放在任何 Sub 或 Funtion 过程头的前面,包括事件过程和声明为 Private 的过程。

    ◆◆

    评论读取中....

    请登录后再发表评论!

    ◆◆

    修改失败,请稍后尝试

    展开全文
  • C++静态成员变量初始化

    千次阅读 2021-06-17 10:35:00
    静态成员变量初始化 静态成员变量可以初始化,但只能在类体外进行初始化。如: long long student::number = 13926572996; //在类体外对静态成员变量赋值 其一般形式为: 数据类型 类名::静态成员变量名 = ...

    静态成员变量初始化

           静态成员变量可以初始化,但只能在类体外进行初始化。如:

    long long student::number = 13926572996;    //在类体外对静态成员变量赋值

    其一般形式为:

    数据类型 类名::静态成员变量名 = 初值;

    不必在初始化赋值语句中加 static。

           注意:不可以在构造函数的参数初始化表中对静态成员变量初始化,例如:

        student(char* pn, char* pa, int n):number(n)

        {

            strcpy(name, pn);

            strcpy(addr, pa);

        }

           在构造函数中,对static类型的number成员进行初始化,是错误的操作。

    如果未对静态成员变量赋值,则编译系统会自动赋初值为0。

    如果一个成员变量定义为const类型,同时,也是static类型,那么,应该怎么样初始化?有如下的分析:

    (1) static类型的成员变量,需要在类外进行初始化;

    (2) const类型的成员变量,需要在构造函数的初始化列表进行初始化;

           那么,const类型的static成员变量,不可以在构造函数的初始化列表中进行初始化,例如:

           程序编译错误,如下:

           提示 student::number成员变量是static类型,仅仅在定义的时候可以初始化。所以,不可以在构造函数列表中初始化。所以,在类外对static类型的成员变量进行初始化,程序测试代码如下:

           程序运行结果如下:

           所以,可以在类外对const类型的静态成员变量进行初始化。

           注意:对于const 类型的static成员变量,可以在定义它的时候进行初始化,如下:

           在student类内对number成员进行初始化。这是合法的语句。

    韦凯峰 Linux C/C++ 程序设计教程,Linux 系统编程,Openwrt 系统开发,微信:13926572996,QQ:1523520001,博客:www.mylinux.vip

    展开全文
  • 静态方法和实例方法的区别主要体现在两个方面: 在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
  • PHP静态成员变量

    2021-01-20 00:58:47
    可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员..因为静态成员存在于内存,所以非静态成员可以直接访问类中静态的成员. 1、...
  • 类中静态成员变量和普通变量的区别——实例代码(VS2010),已测试,没有问题。
  • C++的静态成员变量和静态成员函数

    万次阅读 2019-05-22 15:35:41
    C++的静态成员变量和静态成员函数 静态成员变量和静态成员函数算是C++面向对象编程中的一个重点和难点,这里的静态具体指什么呢?与普通的成员变量和成员函数相比,静态成员函数和静态成员变量是属于类的,而不是...
  • C++类中的静态成员变量和静态成员函数的作用
  • 静态成员变量与非静态成员变量

    千次阅读 2017-06-08 09:03:23
    静态成员变量从属于一个类而非某个具体的对象,它的值被该类的所有对象所共享.对于public的静态成员变量而言,它既可以由类名直接通过 “.” 操作符引用,也可以由对象名通过“.”操作符来引用,并且两者效果相同. 静态...
  • 文章目录类中静态成员变量与静态成员函数的特点静态成员变量示例代码typeid运算符静态成员函数示例代码this指针访问权限 类中静态成员变量与静态成员函数的特点 在类中以static 修饰的变量以及函数称为静态成员变量...
  • 静态成员变量值是所有类的实例共享的,所以调用的时候只需要 类名.属性名 就可调用(也只能这样调用),而非静态成员变量的值是各个实例私有的,所以调用的时候必须是先有具体的类的实例,然后通过实例名来调用。也...
  • a) 静态成员变量: 方法区的静态区域 b) 非静态成员变量: 堆内存中的对象空间里面 2、从书写格式上看: a) 静态成员变量: 在数据类型前面多了一个static修饰 b) 非静态成员变量: 没有static修饰 3、从...
  • 在java中,成员变量分为两种:实例成员变量和静态成员变量。 1.1.1实例成员变量 实例成员变量:是定义在方法外部和类内部的且不被static所修饰的变量.用于描述一个类中包含哪些数据 代码示例: class Person ...
  • C++静态成员变量初始化和赋值

    万次阅读 2019-03-07 14:29:57
    这里说一下C++静态成员变量,在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用。所以在所有对象中都可以共享它。使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的...
  • C++ static静态成员变量用法

    千次阅读 2019-09-28 22:47:25
    C++ static静态成员变量用法 参考网址: 1、http://c.biancheng.net/cpp/biancheng/view/209.html 2、https://www.runoob.com/cplusplus/cpp-static-members.html c++中: 1、在.h文件的类中定义静态的public ...
  • C++中类的(static)静态成员变量与(static)静态成员函数

    万次阅读 多人点赞 2018-08-04 11:27:28
    而在C++的类中,也有静态成员变量同时还有静态成员函数,先来看看C++中静态成员变量与静态成员函数的语法: #include &lt;iostream&gt; #include &lt;string&gt; using namespace std; class ...
  • java中静态成员变量的使用

    千次阅读 2018-11-27 16:16:27
    解释下,这里就是将原来静态成员变量ff改为局部变量,这样每次方法体内的ff就会随着每次调用init方法从新申请的栈中从新创建一个ff的引用,即ff不再唯一,而销毁按钮可以利用this调用是因为button是处在Form2容器中...
  • 在A中定义有全局变量X(或类的静态成员变量),则在动态库B中访问的X,与可执行程序C中访问的X是同一个变量还是两个不同的变量? 答案:是两个不同的变量。 2. 工程中包含动态库A,动态库B,可执行程序C。C依赖于A和...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 471,313
精华内容 188,525
关键字:

静态成员变量

友情链接: svery-pass.zip