实例成员指针

  • 实例成员指针是指向实例成员的指针,可分为实例数据成员指针和实例函数成员指针
  • 构造函数不能被显式调用且只能执行一次,所以不能有指向构造函数的实例成员指针
  • 运算符为 .*->*
  • 实例成员指针是成员相对于对象首地址的偏移,不是真正代表地址的指针
  • 实例成员指针不能移动
  • 实例成员指针不能转换类型

C++-实例成员指针

静态成员指针

  • 静态成员指针前不用加类作用域
  • 静态数据成员指针与普通的变量指针相同
  • 静态函数成员指针与普通的函数指针相同

C++-静态成员指针.jpg

案例

  • 静态成员指针存放成员地址,实例成员指针存放成员偏移
  • 静态成员指针可以移动,实例成员指针不能移动
  • 静态成员指针可以强制类型转换,实例成员指针不能强制转换类型

C++-成员指针案例.jpg

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()