C++类和对象--指向类成员的指针
1. 指向普通变量和函数的指针
#include <iostream>
using namespace std;
void func(int a)
{
cout<<a<<endl;
}
int main()
{
int a = 100;
int *p = &a;
cout<<*p<<endl;
void (*pf)(int) = func;
pf(10);
return 0;
}
2. 指向类数据成员的指针
2.1 定义
<数据类型><类名>::*<指针名>
2.2 赋值&初始化
<数据类型><类名>::*<指针名>[=&<类名>::<非静态数据成员>]
指向非静态数据成员的指针在定义时必须和类相关联,在使用时必须和具体的对象关联。
2.3 解引用
由于类不是运行时存在的对象。因此,在使用这类指针时,需要首先指定类的一个对象,然后,通过对象来引用指针所指向的成员。
<类对象名>.*<指向非静态数据成员的指针>
<类对象指针>->*<指向非静态数据成员的指针>
2.4 案例
#include <iostream>
using namespace std;
class Student
{
public:
Student(string n, int nu):name(n),num(nu){}
string name;
int num;
};
int main()
{
Student s("zhangsan",1002);
Student s2("lisi",1001);
//string *ps = &s.name;//指向非静态数据成员的指针在定义时必须和类相关联
//cout<< *ps<<endl;
string Student::*ps = &Student::name;
cout<<s.*ps<<endl;
cout<<s2.*ps<<endl;
Student *pp = new Student("wangwu",1003);
cout<<pp->*ps<<endl;
return 0;
}
3. 指向类成员函数的指针
定义一个指向非静态成员函数的指针必须在三个方面与其指向的成员函数保持一致:参数列表要相同、返回类型要相同、所属的类型要相同。
3.1 定义
<数据类型>(<类名>::*<指针名>)(<参数列表>
3.2 赋值&初始化
<数据类型>(<类名>::*<指针名>)(<参数列表>)[=&<类名>::<非静态成员函数>]
3.3 解引用
由于类不是运行时存在的对象。因此,在使用这类指针时,需要首先指定类的一个对象,然后,通过对象来引用指针所指向的成员。
(<类对象名>.*<指向非静态成员函数的指针>)(<参数列表>)
(<类对象指针>->*<指向非静态成员函数的指针>)(<参数列表>)
3.4 案例
#include <iostream>
using namespace std;
class Student
{
public:
Student(string n, int nu):name(n),num(nu){}
void dis()
{
cout<<"name "<<name<<" num "<<num<<endl;
}
private:
string name;
int num;
};
int main()
{
Student s("zhangsan",1002);
Student s2("lisi",1001);
Student *ps = new Student("lisi",1003);
void (Student::*pf)() = & Student::dis;
(s.*pf)();
(s2.*pf)();
(ps->*pf)();
return 0;
}
3.5 应用之实现隐蔽接口
用指向类成员函数的指针,实现更加隐蔽的接口。
#include <iostream>
using namespace std;
class Widget
{
public:
Widget()
{
fptr[0] = &Widget::f;
fptr[1] = &Widget::g;
fptr[2] = &Widget::h;
fptr[3] = &Widget::i;
}
void select(int idx, int val)
{
if(idx<0 || idx>cnt) return;
(this->*fptr[idx])(val);
}
int count()
{
return cnt;
}
private:
void f(int val){cout<<"void f() "<<val<<endl;}
void g(int val){cout<<"void g() "<<val<<endl;}
void h(int val){cout<<"void h() "<<val<<endl;}
void i(int val){cout<<"void i() "<<val<<endl;}
enum{ cnt = 4};
void (Widget::*fptr[cnt])(int);
};
int main()
{
Widget w;
for(int i=0; i<w.count(); i++)
{
w.select(i,1);
}
return 0;
}
4. 指向类静态成员的指针
- 指向类静态数据成员的指针
指向静态数据成员的指针的定义和使用与普通指针相同,在定义时无须和类相关联,在使用时也无须和具体的对象相关联。 - 指向类静态成员函数的指针
指向静态成员函数的指针和普通指针相同,在定义时无须和类相关联,在使用时也无须和具体的对象相关联。
#include <iostream>
using namespace std;
class A
{
public:
static void dis();
static int data;
};
void A::dis()
{
cout<<data<<endl;
}
int A::data = 100;
int main()
{
int *p = &A::data;
cout<<*p<<endl;
void (*pfunc)() = &A::dis;
pfunc();
return 0;
}