1、静态成员变量的用法:
//声明
static 数据类型 成员变量; //在类的内部
//初始化
数据类型 类名::静态数据成员 = 初值; //在类的外部
//调用
类名::静态数据成员
类对象.静态数据成员
2、静态成员变量的几点总结:
2.1 static 成员变量实现了同类对象间信息共享。
2.2 static 成员存储在类的外边,求类大小,并不包含在内。
2.3 static 成员只能类外初始化。
2.4 可以通过类名访问(无对象生成时亦可),也可以通过对象访问。
3、静态成员函数的用法:
//声明
static 函数声明
//调用
类名::函数调用
类对象.函数调用
4、静态成员函数的几点总结:
4.1 静态成员函数的意义,不在于信息共享,数据沟通,而在于管理静态数据成员, 完成对静态数据成员的封装。
4.2 静态成员函数只能访问静态数据成员。(原因往下看)
5、相关函数演示
class AA
{
public:
AA(int a, int b)
{
m_a = a;
m_b = b;
}
int getC()
{
cout << "c = " << m_c << endl;
m_c++;
return m_c;
}
static int getCC()
{
return m_c;
}
static int m_c;//1 静态成员变量的申明,在类的内部去写
private:
int m_a;
int m_b;
};
//2 静态成员变量的初始化, 在类的外部去写
int AA::m_c = 0;
int main(void)
{
AA aa1(10, 20), aa2(100,200);
aa1.getC();
aa2.getC();
//修改一个静态的成员变量
// aa1.m_c = 200;
AA::m_c = 200;
cout << "sizeof(aa1) :" << sizeof(aa1) << endl; //8
cout << "sizeof(aa2) :" << sizeof(aa2) << endl; //8 说明函数和static修饰的成员变量都不属于对象。
aa1.getC();
aa2.getC();
return 0;
}
从上述代码中可以看出,静态成员变量和函数都不属于成员变量。那我们用getC函数去获取时,为什么不会出错呢??
也就是说getC 不属于aa1,也不属于aa2。那aa1.getC() 是如何做到访问aa1中的成员变量的呢???
下面引入this指针:
6、this指针
6.1 C++类对象中的成员变量和成员函数是分开存储的
6.2 普通成员变量:存储于对象中,与struct变量有相同的内存布局和字节对齐方式
6.3 静态成员变量:存储于全局数据区中
6.4 成员函数:存储于代码段中
6.5 C++中类的普通成员函数都隐式包含一个指向当前对象的this指针。
6.6 静态成员函数与普通成员函数的区别:静态成员函数不包含指向具体对象的指针(因为他属于类)
普通成员函数包含一个指向具体对象的指针(因为他属于某一个成员)
这就解释了4.2中为什么静态成员函数只能访问静态数据成员。
6.7 this指针就是当前对象的地址,所以 *this可以用来返回当前对象本身。
7、相关函数演示:
class Test
{
public:
Test(int k)
{
this->m_k = k;
this->m_q = 0;
}
Test(int k, int q)
{
this->m_k = k;
this->m_q = q;
}
int getK()
{
//this->m_k = 0;//编译可以通过,说明不是(Test const * this)类型。
//this++;//编译不能通过,说明this是一个常指针(Test * const this)
return this->m_k;
}
int getKK() const
{
//在成员函数后面加const 修饰的不是函数,修饰的是隐藏的this指针
//最后相当于是 int getK(const Test *const this)
return this->m_k;
}
private:
int m_k;
int m_q;
};
int main(void)
{
Test t1(10); // Test t1(&t1, 10)
Test t2(20);
t1.getK();
t2.getK(); // t2.getK(&t2)
return 0;
}