指向非静态成员指针和指向静态成员指针

来源:互联网 发布:网络做印刷怎么找客户 编辑:程序博客网 时间:2024/05/18 01:19

指向类的非静态成员的指针

       类的成员都是变量、对象、函数等,我们同样可以定义存放它们的地址的指针,从而使指针指向对象的成员,通过指针就可以访问对象的成员了。但是通过这种指向成员的指针一样也只能访问公有成员。

       声明指向非静态成员的指针的语法形式为:

       类型说明符 类名::*指针名;                    // 声明指向公有数据成员的指针
       类型说明符 (类名::*指针名)(形参表);          // 声明指向公有成员函数的指针

       指向成员的指针也要先声明再赋值,然后才能引用。给指向成员的指针赋值就是要说明此指针指向类的哪一个成员。

       为指向数据成员的指针赋值的语法形式为:

       指针名 = &类名::数据成员名;

       在前面的地址相关运算中,鸡啄米讲到,用“&”运算符可以取到变量的地址,将其赋值给某个指针后就可以通过这个指针访问变量了。但是对于指向类的数据成员的指针就不同了,在类声明时并不会为类的数据成员分配内存空间,所以给指向数据成员的指针赋值只是确定了此指针指向哪个数据成员,同时也在指针中存放了该数据成员相对于类的起始地址的地址偏移量。这时通过赋值后的指针不能访问到具体的数据成员。

       在声明了类的对象后就会为对象分配内存,这样根据对象的起始地址和指向数据成员的指针中存放的偏移量就可以访问到对象的数据成员了。通过对象和指向数据成员的指针访问公有数据成员的语法形式为:

       对象名.*指向数据成员的指针名
       或者 对象指针名->*指向数据成员的指针名

       为指向成员函数的指针赋值的语法形式为:

       指针名 = &类名::函数成员名;

       在上面的形式为成员函数指针赋值以后还不能直接用此指针调用成员函数,必须先声明了类的对象,再通过对象和指向非静态成员函数的指针调用成员函数。调用的语法形式为:

       (对象名.*指向成员函数的指针名)(形参表)
       或者 (对象指针名->*指向成员函数的指针名)(形参表)

       在为成员函数指针赋值时,还有用对象和成员函数指针调用成员函数时,我们都要注意成员函数指针的返回值类型和形参表一定要和指向的成员函数一致。

       鸡啄米再以上面对象指针中的例子为基础修改下,让大家看看访问对象公有成员函数的几种方式:

       int main()
       {
                 CStudent student(17);      // 声明对象student并对其初始化
                 CStudent *ptr;             // 声明对象指针
                 int (CStudent::*pGetAge)();// 声明指向成员函数GetAge的指针

                 pGetAge = &CStudent::GetAge;// 为pGetAge赋值
                 ptr = &student;             // 初始化对象指针
                 cout << student.GetAge() << endl;   // 通过对象名访问成员函数
                 cout << ptr->GetAge() << endl;      // 通过对象指针访问对象的成员函数
                 cout << (student.*pGetAge)() << endl; // 通过成员函数指针访问成员函数
                 return 0;
        }

       上面的例子中,先声明了一个CStudent类的对象student并初始化,又分别声明了一个指向对象student的指针ptr和指向成员函数GetAge的指针并各自初始化后,分别通过对象名、对象指针和指向成员函数的指针这三种方式访问公有成员函数GetAge。程序的运行结果是:

       17
       17
       17

       四.指向类的静态成员的指针

       上面说了类的非静态成员的指针的概念和使用方法,对于类的静态成员,我们可以用普通指针存放它的地址,通过普通指针访问它。

       鸡啄米再把CStudent类的例子修改下,说明怎样通过指向类的静态数据成员的指针访问静态数据成员:

       #include <iostream>
       using namespace std;
       class CStudent
       {
       public:
                   CStudent(int nAge=15)   { m_nAge = nAge; m_nCount++; }       // 构造函数
                   CStudent(CStudent &stu);                         // 拷贝构造函数
                   int GetAge()            { return m_nAge; }       // 内联函数,返回m_nAge
                   static int m_nCount;   // 静态数据成员声明
       private:
                   int m_nAge;          // 私有数据
       };
       CStudent::CStudent(CStudent &stu)
       {
                  m_nAge = stu.m_nAge;
                  m_nCount++;
       }
       int CStudent::m_nCount = 0;   // 静态数据成员初始化
       int main()
       {
                 int *pCount = &CStudent::m_nCount;  // 声明一个int型的指针,指向静态数据成员m_nCount
                 CStudent student1(17);              // 声明对象student1并对其初始化    
                 cout << "student1:" << student1.GetAge() << endl;
                 cout << "student id=" << *pCount << endl;      // 通过指针访问静态数据成员
                 CStudent student2(student1);                   // 声明对象student2并用student1初始化它
                 cout << "student2:" << student2.GetAge() << endl;
                 cout << "student id=" << *pCount << endl;      // 通过指针访问静态数据成员
                 return 0;
       }

       程序运行结果是:

       student1:17
       student id=1
       student2:17
       student id=2

0 0
原创粉丝点击