目录
一、指向对象的指针
二、指向对象成员的指针
1 指向对象公有数据成员指针
a.定义数据成员的指针变量
b.计算公有数据成员的地址
2指向对象成员函数的指针
a、定义指向成员函数的指针变量
b、取成员函数的地址
c、给指针变量赋初始值
d、 用指针变量调用成员函数
3、this指针
一、指向对象的指针
1、什么是指针?
指针即地址,地址即指针,地址是常量,地址是一个无符号数,是一个无符号的常量,
在32位系统中,地址的范围是从0到2的32次方-1(4GB)//4294967296
2、什么是指针变量?
指针变量即地址变量,地址变量即指针变量,指针变量是变量,既然是变量就有类型;
指针变量是存放指针的变量,即指针变量就是存放地址的变量;
3、什么是对象指针?
对象要占据一片连续的内存空间,CPU实际都是按地址访问内存,所以对象在内存的起始地址是CPU确定对象在内存中位置的依据。
指向对象的指针:也就是指针变量中存放的就是上面说的对象的在内存的起始地址。
4、怎么用
C++对象也可以用取地址运算:&对象名
格式如下:
类名 *变量名表; (类名表示可以指向哪类的对象)
//C++中定义对象的指针变量与定义其他的指针变量相似
定义好指针变量后,必须先给赋予合法的地址后才能使用。
<span style="white-space: pre;"> </span>Time *pt; //定义pt是指向Time类对象的指针
Time t1; //定义Time类对象t1
pt = &t1; //将对象t1的地址赋予pt对象指针
<p align="left">综合案列</p><pre name="code" class="cpp">/************************************************************
*版权所有 (C) http://blog.csdn.net/chentaowangyuanyuan
*
* 文件名称: 对象指针
* 文件标识: 无
* 内容摘要: 创建对象指针,用对象指针调用对象的成员函数
* 当前版本: 1.0
* 作 者: 陈涛
* 完成日期: 2015-07
*
***************************************************************/
#include "stdafx.h"
#include "iostream"
using namespace std;
class TClock
{
public:
TClock(int h = 0, int m = 0, int s = 0) :hour(h), minute(m), second(s){}
void SetTime();
void ShowTime() const;
private:
int hour, minute, second;
};
void TClock::SetTime()
{ //范围限制条件省略
cout << "请输入小时数:";
cin >> hour;
cout << "请输入分钟数:";
cin >> minute;
cout << "请输入秒钟数:";
cin >> second;
cout << endl << endl;
}
void TClock::ShowTime() const
{
cout << "您设定的时间为: " << hour << "时" << minute << "分" << second << "秒" << endl << endl;
}
int main()
{
cout << "对象直接调用---------------------" << endl;
TClock t1; //调用构造函数建立对象
t1.ShowTime();
t1.SetTime(); //调用成员函数从键盘输入时分秒
t1.ShowTime();
cout << "通过对象指针调用------------------" << endl;
TClock t2; //定义TClock类对t2
TClock* p; //定义p是指向TCLock类对象的指针
p = &t2; //将对象t2的地址付给p对象指针
p->SetTime(); //对象指针调用成员函数从键盘输入时分秒 等价于(*p).SetTime()
p->ShowTime(); //
return 0;
}
二、指向对象成员的指针
对象由成员组成。对象占据的内存区是各个数据成员占据的内存区的总和。
对象成员也有地址,即指针。
这指针分指向数据成员的指针和指向成员函数的指针。
1指向对象公有数据成员指针
a.定义数据成员的指针变量
数据类型 *指针变量名
b.计算公有数据成员的地址
&对象名.成员名
例如:
在上述案例中增加一个公有成员int k;
构造函数改为
TClock(int h = 0, int m = 0, int s = 0,int l=0) :hour(h), minute(m), second(s),k(l){}
nt main()
{
cout << "指向数据成员的指针---------------------" << endl;
TClock t1;
cout << t1.k << endl; //k为公有的,所以此处可以调用,初始化是默认为0
t1.k = 20; //设置为t1的数据成员k为20
int* p;
p = &t1.k; //把公有数据成员k的地址赋给了p
cout << p << endl; //p变量的值也就是k的地址
cout << &t1.k << endl; //同样是输出k的地址
cout << *p << endl; //输入p所指向的地址中的数值而不是地址值
cout << t1.k << endl; //输入k中的值
return 0;
}
2.2 指向对象成员函数的指针
2.2.1用在哪里?
在事件驱动和多线程应用中被广泛用于调用回叫函数。
在多线程应用中,每个线程都通过指向成员函数的指针来调用该函数。
2.2.2调用步骤和格式
a、定义指向成员函数的指针变量
数据类型(类名::*变量名)(参数);
数据类型是成员函数的返回值类型
类名是对象所属的类
变量名按标识符取名
形参表:指定成员函数的形参表(形参个数、类型)
b.取成员函数的地址
&类名::成员函数名 //没有括号
c.给指针变量赋初始值
指针变量名=&类名::成员函数名;
d.用指针变量调用成员函数
(对象名.*指针变量名)([实参表]);
对象名:是指定调用成员函数的对象.
*: 明确其后的是一个指针变量。
实参表:与成员函数的形参表对应,如无形参,可以省略实参表。
<span style="white-space:pre"> </span>void Get_time(); //声明 获取时间的成员函数
//格式:<span style="white-space: pre;"> </span>数据类型(类名::*变量名)(参数);
void(Time::*p3)(); //定义指向成员函数的指针
p3 = &Time::Get_time; //给成员函数的指针赋值
(t1.*p3)(); //用指向成员函数的指针调用成员函数<span style="font-weight: bold;">
</span>
综合实例
/************************************************************
*版权所有 (C) http://blog.csdn.net/chentaowangyuanyuan
*
* 文件名称: 指向对象成员函数的指针
* 文件标识: 无
* 内容摘要: 通过用对象,对象的指针,对象成员函数的指针3中方法来调用对象的成员函数
* 当前版本: 1.0
* 作 者: 陈涛
* 完成日期: 2015-07
*
***************************************************************/
#include "stdafx.h"
#include "iostream"
using namespace std;
class Time
{
public:
Time(int h = 0, int m = 0, int s = 0) :hour(h), minute(m), second(s){}
void ShowTime();
private:
int hour, minute, second;
};
void Time::ShowTime()
{
cout << "您设置的时间为:" << hour << "时" << minute << "分" << second << "秒" << endl;
}
int main()
{
//通过对象直接调用
Time t(5, 5, 5);
t.ShowTime();
//通过对象的指针调用成员函数
Time* p;
p = &t; //定义指向对象t的指针p
p->ShowTime(); //用对象指针调用成员函数
//通过指向成员函数的指针调用成员函数
//格式:数据类型(类名::*变量名)(参数);
void(Time::*p1)(); //定义指向成员函数的指针
p1 = &Time::ShowTime; <span style="white-space: pre;"> </span>//注意此时的函数没有()
(t.*p1)(); //用指向成员函数的指针调用成员函数
return 0;
}
<img src="https://img-blog.csdn.net/20150812220427227" alt="" />
2.3 this指针
一个类的成员函数只有一个内存拷贝。
类中不论哪个对象调用某个成员函数,调用的都是内存中同一个成员函数代码。
例如Time类一个成员函数
void Time::Get_time()
{
cout<< hour << ":"<< minute <<":"<< sec << endl;
}
T1.Get_time();
T2.Get_time();
当不同对象的成员函数访问数据成员时,怎么保证访问的就是本对象的数据成员?
结论:其实每个成员中都包含一个特殊的指针,它的名字是this。它是指向本对象的指针。
this指针记录每个对象的内存地址,然后通过运算符->访问该对象的成员。
举例证明:
#include "stdafx.h"
#include "iostream"
using namespace std;
class X
{
public:
X(int x, int y)
{
this->a = x;
this->b = y;
cout << "this指针中保存的地址" << this << endl;
cout << "a的地址为" << &a << endl;
cout << "b的地址为" << &b << endl;
}
void show()
{
cout << "a=" << a << " " << "b=" << b << endl;
}
private:
int a, b;
};
int main()
{
X m(1, 2);
cout << "m的地址" << &m << endl;
cout << "m.show的地址" << &X::show << endl;
cout << endl << endl;
X n(2, 3);
cout << "n的地址" << &n << endl;
return 0;
}
通过上述结果,可以看出对象m的内存地址和this指针和m对象中第一个数据成员一模一样,
换做n时也都变成了(0026FA68),
说明this指针记录的是当前对象的内存地址,也就是上面说的this指针指向当前的对象。
而定义X m;时调用构造函数中的this->a=x,说明把x的值赋给了当前对象(也就是m)的私有成员a.
从而证明了上面的结论:this指针它保存了当前对象的地址,并且应用指针的形式指向了当前的对象