class Time
{
public:
int hour;
int sec;
void get_time();
}
void Time::get_time()
{cout << hour << ":" << minute << ":" << sec << endl; }
在此基础上,可以这么定义:
Time *pt; //定义pt为指向Time类对象的指针变量
Time t1; //定义t1为time类对象
pt = &t1; //将t1的起始地址赋给pt
定义类对象的指针变量的一般格式为:
类名 * 对象指针名
*pt; //pt指向的对象,t1
(*pt).hour; //pt指向的对象中的hour成员,即t1.hour
pt -> hour; //pt指向的对象中的hour成员,即t1.hour
(*pt).get_time(); //调用pt所指的对象中的get_time函数,即t1.get_time
(*pt) -> get_time(); //调用pt所指的对象中的get_time函数,即t1.get_time
注意两种写法想过一样。
对象有地址,存放对象初始地址的指针变量就是指向对象的指针变量。
对象中成员也有地址,存放对象成员地址的指针变量就是指向对象成员的指针变量。
下面又细分两大类:
<1> 对象数据成员的指针
数据类型名 * 指针变量名;
如果Time类的数据成员是public,并且hour为整型数据。那么可以在类外通过指向对象数据成员的指针变量访问对象数据成员hour。
int *p1; //定义指向整型数据的指针变量
p1 = &t1.hour; //将对象t1的数据成员hour的地址赋给p1,p1指向t1.hour
cout << *p1 << endl; //输出t1.hour
<2> 对象成员函数的指针
下面先看一下普通函数的指针变量的定义方法:
void (*p)(); //p是指向void型函数的指针变量
p = fun; //fun函数的入口地址赋给指针变量p,p就指向了函数fun
(*p)(); //调用fun函数
而定义指向共用成员函数的指针变量的一般形式为:
数据类型名(类名::*指针变量名)(参数列表);
指针变量指向一个公用成员函数的一般形式为:
指针变量名 = &类名::成员函数名;
#include <iostream>
using namespace std;
class Time
{
public:
Time(int h, int m, int s); //constructor
int hour;
int minute;
int sec;
void get_time(); //public member function
~Time() //destructor
{
cout << "Destructor called " << hour << endl;
}
};
Time::Time(int h, int m, int s) //constructor
{
hour = h;
minute = m;
sec = s;
}
void Time::get_time()
{
cout << hour << ":" << minute << ":" << sec <<endl;
}
int main()
{
Time t1(10, 13, 56); //定义Time类对象t1
int *p1 = &t1.hour; //定义整型指针变量p1,并使p1指向对象t1的公共数据hour
cout << *p1 << endl; //输出指针变量p1所指的数据成员的内容
t1.get_time(); //输出对象t1的成员函数get_time
Time *p2 = &t1; //定义Time类的指针变量t2,并使p2指向对象t1
p2 -> get_time(); //调用p2所指对象的t1的get_time函数
void (Time::*p3)() = &Time::get_time; //定义指向Time类的共有成员函数的指针变量p3,并使指向Time类的公用成员函数get_time
(t1.*p3)(); //调用对象t1中p3所指的成员函数
return 0;
}
说明:
成员函数的入口地址的正确写法是:
&类名::成员函数名
不能写成
p3 = &t1.get_time; //t1为对象名
因为成员函数不是存放在对象空间中,而是存放在对象外的空间中。所以用类名指向函数代码段。
每个对象中的数据成员分别占用存储空间。如果对同一类定义了n个对象,则有n组同样大小的空间存放n个对象的数据成员。不同的对象调用同一个函数代码段。笼统的来说,不同对象数据成员地址不同,但是对象函数相同。
那么有个问题,不同的对象调用同一个成员函数,怎么保证每个对象调用的是各自对象的数据成员呢?
每个成员函数都包含一个特殊的指针,名字是固定的,称为this。它的值就是当前被调用的成员函数所在的对象的起始地址。例如当调用成员函数a.volume时,编译系统就把对象a的起始地址赋给this指针,于是在调用成员函数时,就按照this的指向找到对象a的数据成员。例如volume函数要计算height * width * length的值实际上计算的是(this -> height)* (this -> width) * (this -> length),由于当前this指向对象a,因此相当于执行:(a -> height)* (a -> width) * (a -> length),这样就计算出长方体a的体积。this指针是隐式的,作为参数被传递给成员函数的。“调用对象a的成员函数f”实际是指“调用成员函数f时使this指针指向对象a,从而访问对象a的数据成员”。