上篇C++57个入门知识点_42:静态成员变量理解(static int m_nStatic;实现单独写在类外;本质是带类域的全局变量;可以不用产生对象即可访问CInteger::m_nStatic=1)介绍了静态成员变量,本篇将会介绍静态成员函数,static
关键字不仅可以修饰静态成员变量,还可以修饰成员函数。
静态成员函数总结:
- 静态成员函数的定义:
- 静态成员函数声明:
static void foo();
- 静态成员函数实现:
void CInteger::foo(){ printf("CInteger::foo()"); }
- 静态成员函数的调用:生成对象进行调用,
CInteger i = 1; i.foo();
-
静态函数内部不能访问普通成员变量,只能访问静态成员变量;
-
静态成员函数无法访问普通成员变量的本质是静态成员函数中没有
this
指针; -
静态成员函数本质上就是带类域的全局函数,可以直接利用类调用静态成员函数,并避免名称冲突的问题;
-
利用静态成员函数中没有
this
指针的本质,在线程及回调函数中会用到静态成员函数,用作线程的回调函数的声明。
1. 静态成员函数的定义
本篇还是在上篇代码的基础上,对代码进行修改。项目结构如下:
- 静态成员函数声明:
static void foo();
CIntreger.h
:
class CInteger
{
public:
CInteger(int nNumber) {
m_nNumber = nNumber;
}
int GetNumber()const;
void SetNumber(int nNumber) {
m_nNumber = nNumber;
}
static void foo();
static int m_nStatic;
private:
int m_nNumber;
};
- 静态成员函数实现:
void CInteger::foo(){ printf("CInteger::foo()"); }
CIntreger.cpp
:
#include "CIntreger.h"
#include <iostream>
int CInteger::GetNumber()const
{
return m_nNumber;
}
int CInteger::m_nStatic = 123;
void CInteger::foo()
{
printf("CInteger::foo()");
}
- 静态成员函数的调用:生成对象进行调用,
CInteger i = 1; i.foo();
testCPP.cpp
:
#include <iostream>
#include "CIntreger.h"
int main()
{
CInteger i = 1;
i.foo();
return 0;
}
2. 函数内部不能访问普通成员变量,只能访问静态成员变量
- 在静态成员函数内部调用类的普通成员变量,显示错误
void CInteger::foo()
{
printf("CInteger::foo()");
m_nNumber = 1;//编译后显示对非静态成员“CInteger::m_nNumber”的非法引用
}
运行结果:
- 在静态成员函数内部调用类的静态成员变量,编译正常
void CInteger::foo()
{
printf("CInteger::foo()");
m_nStatic = 2;
}
3. 静态成员函数无法访问普通成员变量的本质
出现上面的原因是:静态成员函数中没有this
指针,导致无法访问普通成员变量m_nNumber,而m_nStatic
不属于某个对象,而是属于类的,因此可以直接访问
成员函数是所有对象所所共有的,为了指明调用成员函数的对象,因此成员函数中会默认多一个对象的参数,这是我们所看不到的。参考C++57个入门知识点_18_ 类的大小+成员函数性质+this指针(类大小由成员变量决定;类对象数据独立,成员函数共用;this指针:谁创建指向谁,谁使用成员函数指向谁;类成员函数指针写法及调用)。
void CInteger::foo()
{
printf("CInteger::foo()");
m_nStatic = 2;
void* p = this;//报错:“this”只能用于非静态成员函数内部;只能在非静态成员函数或非静态数据成员初始值设定项的内部引用
}
编译结果:
4. 静态成员函数本质上就是带类域的全局函数,可以避免名称冲突的问题
与静态成员变量相似,静态成员函数不依赖于对象,因此在对象不存在的情况下也是可以进行访问的。
int main()
{
CInteger i = 1;
i.foo();
//因为静态成员函数没有this指针,因此也不需要依赖对象,故可以写成如下:
CInteger::foo();
//不用创建对象就可以创建静态变量,因为它是与类相关的,一个类有一个
//属于类而不单属于某个对象,是类公有的
//CInteger::表示在类域范围内
CInteger::m_nStatic = 1;
return 0;
}
5.学习视频地址:C++57个入门知识点_43:静态成员函数