实例成员指针
- 实例成员指针是指向实例成员的指针,可分为实例数据成员指针和实例函数成员指针
- 构造函数不能被显式调用且只能执行一次,所以不能有指向构造函数的实例成员指针
- 运算符为
.*
和->*
- 实例成员指针是成员相对于对象首地址的偏移,不是真正代表地址的指针
- 实例成员指针不能移动
- 实例成员指针不能转换类型
静态成员指针
- 静态成员指针前不用加类作用域
- 静态数据成员指针与普通的变量指针相同
- 静态函数成员指针与普通的函数指针相同
案例
- 静态成员指针存放成员地址,实例成员指针存放成员偏移
- 静态成员指针可以移动,实例成员指针不能移动
- 静态成员指针可以强制类型转换,实例成员指针不能强制转换类型
class Crowd
{
public:
int a;
// 表示在本类中不会修改此变量
// 但其它进程有可能会修改,表示会有多进程并发
volatile int b;
// C++17 支持
// 使用 inline、const 修饰 static 变量可在类体内进行初始化
const static int j = 3;
static int num;
public:
Crowd();
Crowd(int x);
~Crowd();
// 类体内函数定义
// 会被内联处理
int f() {
b++;
cout << "F()\n";
return b;
}
// const this 指针,参数类型不同,所以可被重载
int f()const {
cout << "const F()\n";
return b;
}
static int getNum();
static Crowd& dec(Crowd& a);
};
// 静态成员变量类体外初始化
int Crowd::num = 0;
Crowd::Crowd()
{
a = 0;
b = 0;
Crowd::num++;
cout << "Crowd()\n";
}
Crowd::Crowd(int x): a(x) {
b = 0;
Crowd::num++;
cout << "Crowd(int)\n";
}
Crowd::~Crowd()
{
Crowd::num--;
}
int Crowd::getNum() {
return Crowd::num;
}
Crowd& Crowd::dec(Crowd& a) {
a.a = a.a - Crowd::j;
return a;
}
int main()
{
// 数组会调用无参构造
Crowd* arr = new Crowd[3]{ 1,Crowd(2) }; // 第三个元素使用无参构造函数
// 静态数据成员指针
int* d = &Crowd::num;
// 静态函数成员指针
int (*f)() = &Crowd::getNum;
cout << "Crowd number: " << *d << endl;
Crowd c1;
d = &c1.num; // 等价于 d = &Crowd::num;
cout << "Crowd number: " << *d << endl;
Crowd c2;
cout << "Crowd number: " << (*f)() << endl;
// 实例数据成员指针
int Crowd::* p = &Crowd::a;
// 实例函数成员指针
int (Crowd::* pf)() const = &Crowd::f;
// 无址引用
Crowd&& a = Crowd{ 3 };
Crowd b = Crowd::dec(a);
cout << b.*p << endl;
(b.*pf)();
return 0;
}
输出:
Crowd(int)
Crowd(int)
Crowd()
Crowd number: 3
Crowd()
Crowd number: 4
Crowd()
Crowd number: 5
Crowd(int)
0
const F()