类的成员按照功能包括两种:数据成员和函数成员。 而按照状态又分为静态和非静态。 所以下面将从这几个方面来简介。
一.非静态成员:
一:数据成员
声明语法:
类型说明符 类名::*指针名; //声明指向数据成员的指针,注意这个指针和this指针一样,是每个实例化后的对象共有的
eg:int point::*num_ptr;
对指针赋值的语法:
指针名=&类名::数据成员名
ed:num_ptr=&point::m_a; //num_ptr是上面我们定义的指针的名字,point是我们自定义的类,m_a是point类中的一个数据成员
访问方式:
1.具体实例化的对象名.*类成员指针名
2.具体实例化的对象指针名->*类成员指针名 //看似复杂,其实仔细看看就能和我们之前学过的原理结合上
具体程序实例:
#include <iostream>
using namespace std;
class point {
public:
int m_a;
int m_b;
point(int m_a, int m_b) {
this->m_a = m_a;
this->m_b = m_b;
}
int get_a() {
return m_a;
}
int get_b() {
return m_b;
}
};
int main(){
point p(1,2); point *p1=&p;//定义一个指针去指向p这个整体的大对象
int point::*num_ptr; //定义一个指向类的成员的指针
num_ptr=&point::m_a; //指向m_a这个元素
//调用方法1
cout<<p.*num_ptr<<endl;
//调用方法2
cout<<p1->*num_ptr<<endl;
}
二:函数成员
声明语法:
类型说明符 (类名::*指针名)(参数表,没有参数就为空);
eg: int(point:: * funptr)();
赋值语法:
funptr = &point::get_a;
调用语法:
1.(对象名.*类成员指针名)(参数表)
2.(对象指针名->*类成员指针名)(参数表)
#include <iostream>
using namespace std;
class point {
public:
int m_a;
int m_b;
point(int m_a, int m_b) {
this->m_a = m_a;
this->m_b = m_b;
}
int get_a() {
return m_a;
}
int get_b() {
return m_b;
}
};
int main() {
point p(1, 2);
point* p1 = &p;
int(point:: * funptr)(); //相比于指向数据成员,指向函数的情况也不过就是多了几层括号而已,便于我们简记用法。
funptr = &point::get_a; //注意这里的函数名后面不加()
//调用方法1
cout << (p.*funptr)() << endl;
//调用方法2
cout << (p1->*funptr)() << endl;
//顺便提一下我们之前的两个访问方式,横向对比记忆
cout<<p.get_a()<<endl;
cout<<p1->get_a()<<endl;
}
二:静态成员类型。
一:静态数据成员
#include <iostream>
using namespace std;
class person {
public:
static int count;
person() {
++count;
}
static void print() {
cout << count << endl;
}
};
int person::count = 0;
int main() {
person p;
//与非静态数据成员不同,前半部分定义指针的时候省略了类名
int* p1 = &person::count;
//因为静态成员是类对象共有的,所以不依赖于每个对象,直接解引用就可以
cout << *p1 << endl;
}
二:静态函数成员
#include <iostream>
using namespace std;
class person {
public:
static int count;
person() {
++count;
}
static void print() {
cout << count << endl;
}
};
int person::count = 0;
int main() {
//相比于非静态函数的写法,类的静态函数也是前半部分不用写类名
void (*p2)() = &person::print;
p2();//调用的时候写成p2()或者*p2;
}