【C++静态成员函数不能调用非静态成员变量】

静态成员函数

定义:静态成员函数就是在声明时前面加了 static 关键字的成员函数。

  其实我们从直观上可以很好的理解静态成员函数不能调用非静态成员变量这句话,因为无论是静态成员函数还是静态成员变量,他们都是在类的范畴之外的,及在类的整个生存周期里始终只能存在一份。然而非静态成员变量和非静态成员函数是针对类的对象而言。
  然而从本质上来说类的静态成员函数的函数形参中没有默认的this指针,导致不能调用具体实例对象的成员。

this指针

定义:在C++中,每一个对象都能通过this指针来访问自己的地址。this指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象。
注意:this指针只有在成员函数中才有定义。创建一个对象后,不能通过对象使用this指针。也无法知道一个对象的this指针的位置(只有在成员函数里才有this指针的位置)。当然,在成员函数里,你是可以知道this指针的位置的(可以&this获得),也可以直接使用的。
  在类的非静态成员函数中返回类对象本身的时候,我们可以使用圆点运算符*,箭头运算符->。
案例

#include <iostream>
using namespace std;

class Kuchiki
{
public:
    int A;

public:
    Kuchiki(int data)
    {
        A = data;
    }

    void Show()
    {
        cout << "this:" << this << endl;
        cout << this->A << endl;
        cout << A << endl;
        cout << (*this).A << endl;
    }
};


int main()
{
    Kuchiki per(5);
    per.Show();
    return 0;
}

输出

this:003EFE8C
5
5
5

关于this指针的一个精典回答:
当你进入一个房子后,
你可以看见桌子、椅子、地板等,
但是房子你是看不到全貌了。
对于一个类的实例来说,
你可以看到它的成员函数、成员变量,
但是实例本身呢?
this是一个指针,
它时时刻刻指向你这个实例本身。

C++静态成员函数不能调用非静态成员变量原因

首先先看一个案例

#include <iostream>
using namespace std;

class Kuchiki
{
public:
    static int A;
    int B;

public:
    Kuchiki(int data)
    {
        B = data;
    }

    static void statictestfun()
    {
        cout << "static A = " << A << endl;
    }
};

int Kuchiki::A = 10;

int main()
{
    Kuchiki* per;
    per = new Kuchiki(5);
    Kuchiki::statictestfun();
    return 0;
}

输出
在这里插入图片描述
可以看出,静态成员函数可以成功调用静态成员变量。紧接着,采用静态成员函数来调用非静态成员变量,具体案例如下:

#include <iostream>
using namespace std;

class Kuchiki
{
public:
    static int A;
    int B;

public:
    Kuchiki(int data)
    {
        B = data;
    }

    static void statictestfun()
    {
        cout << "B = " << B << endl;
    }
};

int Kuchiki::A = 10;

int main()
{
    Kuchiki* per;
    per = new Kuchiki(5);
    Kuchiki::statictestfun();
    return 0;
}

输出
在这里插入图片描述
结果编译不能通过,这是什么原因导致的呢?
原因:静态成员函数与静态数据成员一样,都是类的内部 实现,属于类定义的一部分,它为类的全部服务而不是为某一个类的具体对象服务。普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this 是缺省的。但是与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指针。从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。
总结如下

  1. 静态成员变量的函数形参中没有默认的this指针指向类对象本身。所以当我们调用对象的非静态成员变量的时候它不能识别该变量。
  2. 然而对于静态成员变量而言,其存在于整个类中,为每个类对象共有,所以就算没有默认的this形参仍然可以识别该静态成员变量。

为什么要引入static

  函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现? 最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。

什么时候用static

  需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见。

致谢

本文学习参考了以下文章:
https://baike.baidu.com/item/static/9598919
https://www.jb51.net/article/100827.htm

  • 13
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值