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

  • 静态成员函数
  • this指针
  • C++静态成员函数不能调用非静态成员变量原因
  • 为什么要引入static
  • 什么时候用static
  • 致谢

静态成员函数

定义:静态成员函数就是在声明时前面加了 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

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

  1. qt 静态成员变量_Qt 静态成员函数的调用非静态成员变量,非静态成员函数

    在多人开发的项目中,一些通用的工具类接口可以用静态成员函数.方便调用,并且不容易调用错误. 静态成员函数不传递this指针(不能->),不识别对象个体,所以经常用于对静态数据成员进行操作.不能操 ...

  2. 静态成员函数如何调用非静态成员变量

    ◆函数加参数解决方法 1).编译时候静态数据和成员函数就有了它的内存区,它不属于类的任何一个具体对象.所以,静态成员函数在编译时候就需要确定x及y的值,而那个时侯变量x,和y还没有创建,所以不可以访问 ...

  3. 为什么静态方法无法直接调用非静态成员变量和方法

    静态方法无法直接调用非静态成员变量和方法 看到这句话,要想到形容的是这样的如下 静态方法里面无法调用非静态变量 下面在写一个对比非静态的方法和静态方法调用变量对比 问题原因 静态变量和静态的方法是属于 ...

  4. Cpp 对象模型探索 / 类静态成员函数的调用方式

    一.普通静态成员函数的调用方法 栗子: class CA { public:static void func() {} };int main() {CA A;A.func();CA::func();r ...

  5. 类的成员函数指针和静态成员函数指针 调用成员函数***

    C++提供static这个关键词对静态成员进行声明,静态成员函数和类的实例化无关,对于同一类来说,静态成员函数是所有类的对象共享的.而普通成员函数需要实例化才能调用,对于每一个实例来说,普通成员函数是 ...

  6. 为什么静态成员函数可以访问私有成员变量?(访问控制是针对类而不是针对对象)

    访问控制是针对类而不是针对对象 先看几个标准定义 A member of a class can be - private; that is, its name can be used only by ...

  7. php静态方法调用变量吗,php静态方法怎么调用非静态变量?

    php中,静态方法可以使用self关键词来调用非静态变量,例"self::$name":一个方法被"self::"后,它就自动转变为静态方法.注:静态方法不能调 ...

  8. java中对象多态时成员变量,普通成员函数及静态成员函数的调用情况

    /* 样例1:class Parent{int num = 3;}class Child extends Parent{int num = 4;} *//* 样例2: class Parent{}cl ...

  9. 为什么C++静态static函数不能访问非静态成员

    原因如下: 1. 静态static成员函数不同于非静态函数,它只属于类本身,而不属于每一个对象实例.静态函数随着类的加载而独立存在.与之相反的是非静态成员,他们当且仅当实例化对象之后才存在.也就是说, ...

最新文章

  1. servlets_jQuery Ajax – Servlets集成:构建完整的应用程序
  2. 【转】ELK是什么能做什么怎么做
  3. mysql path密码忘记_mysql密码忘记
  4. 算法提高 身份证号码升级
  5. [机器学习实战]决策树
  6. mapgis6.7破解版|mapgis6.7破解版客户端(附安装教程)下载
  7. 管家婆辉煌-- 连接服务器失败处理办法
  8. openwrt配置doh
  9. java spu sku_SPU与SKU区别小结
  10. 吴恩达机器学习MATLAB代码笔记(1)梯度下降
  11. 计算机处理器i3性能,笔记本电脑的CPU i3/i5/i7处理器哪个好?
  12. 大数据告诉你:2019年该学习什么技术
  13. kestrel web服务器性能对比,Asp.Net Core 3.0 Kestrel服务器下 高性能 WebSocket Server
  14. Linux下网络丢包故障定位
  15. 15/18位身份证号码正则表达式(详细版)
  16. Opencv去除高光的算法--Highlights Removal
  17. 【二分图最大独立集】BZOJ4808[马]题解
  18. 性能测试利器 — 全链路监控工具Pinpoint安装教程(非docker版本)
  19. 并查集详解,不会的同学可以来瞅瞅,转载的,不过加了一些自己的理解。
  20. 什么是获客成本 (CAC) 以及如何计算

热门文章

  1. 多种方式发布WebGIS地图服务以及显示
  2. 源代码保密/防泄漏产品种类分析
  3. juicer.js的使用
  4. Kalman Filter与RLS的区别
  5. RFID原理与应用第一章
  6. Excel:如何将vlookup 中#N/A全部替换为0。
  7. 百面机器学习(8)——采样
  8. 【51Nod 1463】 找朋友
  9. javascript实习笔记5
  10. Vue:项目启动时报错These dependencies were not found 解决办法