#C++ Day25 November 7 2025

//Object – Oriented 5 – 5 static member variable

//静态成员变量

#include <iostream>

#include <string>

using namespace std;

/*

静态成员变量的特点:

1.所有的对象共享同一份数据

2.编译阶段分配内存

3.需要在类中进行声明,在类外进行初始化

*/

class Hero {

public:

Hero() {

m_Name = “英雄”;

m_Hp = 100;

}

~Hero() {

}

//3.1声明的过程

static int m_HeroCount;//静态成员变量 它是一个public变量 公共的 加了个static静态的

//静态变量我们需要给它初始化 拷贝出来

private:

string m_Name;

int m_Hp;

};

//3.2初始化的过程

int Hero::m_HeroCount = 100;//加上作用域 就不是全局变量了

int main() {

Hero h;

cout << h.m_HeroCount << endl;//error LNK2001: unresolved external symbol “public: static int Hero::m_HeroCount” (?m_HeroCount@Hero@@2HA)

h.m_HeroCount = 101;

cout << Hero::m_HeroCount << endl; //从类里面拿,输出101 说明对象上的变量和类本身的变量应该都是同一个变量

//猜测的话打印地址就可以验证真伪了

cout << &(h.m_HeroCount) << endl;

cout << &(Hero::m_HeroCount) << endl;

return 0;

}

//Object – Oriented 5 – 6 static member function

//静态成员函数

#include <iostream>

#include <string>

using namespace std;

//静态成员函数内部只能用静态成员变量,不能用普通成员变量

/*

1.所有对象共享函数

2.静态成员函数只能使用静态成员变量,无法使用普通成员变量

*/

class Hero {

public:

Hero() {

m_Name = “Vito”;

m_Hp = 100;

}

~Hero() {

}

//声明一个静态成员变量

static int m_HeroCount;

static int GetHeroCount() { //静态成员函数

//静态的东西在内存里面只有一份 一份的时候去取这个成员的时候 它不知道要取哪个对象的成员 这里是没法访问的

//m_Hp += 1;//不能在静态成员函数里操作非静态成员变量(普通成员变量)

return m_HeroCount;

}

private:

string m_Name;

int m_Hp;

static int GetHeroCount1() { //静态成员函数也可以有访问权限的设置

return m_HeroCount;

}

};

int Hero::m_HeroCount=100;  //初始化

int main() {

Hero h;

cout << h.GetHeroCount() << endl;

cout << Hero::GetHeroCount() << endl;//不从对象h上取

//h.GetHeroCount1();//private的情况下 函数在类外访问不到

return 0;

}

//Object – Oriented 5 – 7 this pointer

//this指针

#include <iostream>

using namespace std;

//类里面就有this这个变量

/*

this 指针

1.解决命名冲突

2.*this 就可以获取到这个对象本身

this *this

&h *(&h)==h

*/

class Hero {

public:

Hero(int hp) { //形参 

//当形参跟成员变量同名的时候   成员变量就被隐藏掉了 也就是被形参覆盖掉了

//hp = hp;//这句话是形参赋值给形参自己 没有意义了 可以靠编译器,直接用鼠标识别是否同一变量

this->hp = hp;//this代表指向对象的指针 通过箭头获取到它的成员变量

cout << this << endl; //打印出十六进制的数据  指针

cout << (*this).hp << endl;

}

int hp;//成员变量

};

int main() {

Hero h(100);//实例化对象

cout << h.hp << endl; //作用域问题

cout << &h << endl;//跟this的地址一样  所以this实际上代表了这个对象的地址

cout << (*(&h)).hp << endl;//跟this的地址一样  所以this实际上代表了这个对象的地址 

//首先取地址 然后解引用 解引用后得到对象本身 然后通过.拿到hp

return 0;

}

//Object – Oriented 5 – 8 const – qualified member function

//const 修饰的成员函数

#include <iostream>

#include <vector> //右键或F12转到文档

using namespace std;

//常函数  成员函数的参数和函数体之间如果加上一个const的关键字 这个函数我们就叫它常函数

//常函数的函数体中不能修改成员属性的值

class Hero {

public:

Hero() :m_Hp(0) {}

int getHp() const {

//m_Hp = m_Hp + 1;//不小心改了一下 为了杜绝这种情况 成员函数加const

//STL c++标准模板库 里面就有这项技术

return m_Hp;

}

int setHp(int hp) {//这里也不能加const 因为加了const左值就改不了了

m_Hp = hp;

}

private:

int m_Hp;

};

int main() {

const Hero h;

//h.setHp(100);//常量调用一个非常量函数不可以 所以对于常量只能调用常函数

h.getHp();

return 0;

}

//Object – Oriented 5 – 9 mutable

//可变

//跟const 相对

//mustable <-> const

#include <iostream>

using namespace std;

class Hero {

public:

Hero():m_Hp(0), m_getHpCounter(0) {}

int getHp() const {//常函数 

//常函数成员变量一般不能改

//里面希望有个变量能进行自增

m_getHpCounter++;//加了mutable可以改,在常量函数里有一个变量统计次数就可以这么写

return m_Hp;

}

void printCounter() const {

cout << “Counter:” << m_getHpCounter << endl;

}

private :

int m_Hp;

mutable int m_getHpCounter;//成员变量加了mutable可以改

};

int main() {

Hero h;

h.getHp(), h.getHp(), h.getHp(), h.getHp(), h.getHp(), h.getHp();

h.printCounter();

return 0;

}