指向对象的指针

在建立对象的时候,变异系统会给每一个对象分配一定的存储空间,以存放其成员。
对象空间的起始地址就是对象的指针。可以定义一个指针变量,用来存放对象的指针。
一个简单的示例1.1:
#include<iostream>
using namespace std;
class Student
{
public:
int num;
int score;
Student(int ,int );//声明构造函数
void Print();//声明输出信息函数
};
Student::Student(int n,int s)
{
num=n;
score=s;
}
void Student::Print(){
cout<<num<<"\t"<<score<<endl;
}
int main(){
Student stud(1,100);//实例化一个对象
Student *p=&stud;//定义一个指向对象的指针,并使用对象stud的地址初始化
cout<<"*p.num:"<<(*p).num<<endl;//使用指向对象的指针调用数据成员的方式一
cout<<"p->score:"<<p->score<<endl;//使用指向对象的指针调用数据成员的方式二
(*p).Print();
p->Print();
return 0;
}



指向对象成员的指针

对象有地址,存放对象初始地址的指针变量就是
指向对象的指针变量
对象中的成员也有地址,存放对象成员地址的指针变量就是
指向对象成员的指针变量

1.指向对象数据成员的指针

定义指向对象数据成员的方法和定义指向普通变量的方法相同:
数据类型    *    指针变量名
p=&t1.hour;//将对象t1的数据成员hour的地址赋给p,p指向t1.hour
cout<<*p<<endl;//输出t1.hour的值

2.指向对象成员函数的指针

定义指向成员函数的指针和定义指向普通函数的指针的方法是不同的。
定义指向普通函数的指针的方法是这样的:
数据类型名(* 指针变量名)(参数列表);
如:
void  (*p)(int n,int m);//p是指向void型函数的指针变量
p=fun;//将fun函数的入口地址赋给指针变量p,p就指向了函数fun
(*p)(a,b);//调用fun函数,其中,a,b是实参

而定义一个指向对象成员函数的指针变量则比较复杂一些。

如果我们直接按照上面的方法定义指针变量,将对象成员函数名赋给指针变量p:
void (*p)();
p=t1.Print();

编译会出现错误
成员函数与普通函数的一个最根本区别:它是类中的一个成员。

编译系统要求上面的复制语句中,指针变量的类型必须与赋值号右侧函数的类型相匹配,要求在一下3个方面要匹配:
1.函数参数的类型和参数个数
2.函数返回值的类型
3.所属的类
前两个是匹配的,而第三点不匹配。
指针变量p与类无关,而Print()却属于Student类。


定义指向成员函数的指针变量应该采用以下形式:
void (Student::*p)();//定义p为指向Student类中公共成员函数的指针变量

数据类型名(类名::*指针变量名)(参数表列);

我们知道,所有的Student类实例化得到的对象都是公用一个成员函数的,所以我们没有必要指定它是指向那个对象的成员函数的指针,我们只需要定义它是指向该类的成员函数就可以了。

使
指针变量指向一个公用成员函数的一般形式为:
p=&Student::Print;

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

在使用时,仍然需要将指针放到具体的对象中使用,(*p)的作用等价于Print()
stud.(*p);//作用与stud.Print()的作用等价

=================一个使用对象指针的例子1.2===========
#include<iostream>
using namespace std;
class Student
{
public:
int num;
int score;
Student(int ,int );
void Print();
};
Student::Student(int n,int s)
{
num=n;
score=s;
}
void Student::Print(){
cout<<num<<"\t"<<score<<endl;
}
int main(){
Student stud(1,100);
cout<<"stud.Print()"<<endl;
stud.Print();//直接调用对象stud的成员函数Print();
Student *p_class=&stud;//定义指向对象stud的指针;
cout<<"p_class->Print()"<<endl;
p_class->Print();//通过指向对象的指针调用成员函数Print();
void (Student::*p_fun)();//声明p_fun是指向Student中的函数的指针
p_fun=&Student::Print;//是p_fun指向Student类公用成员函数Print()
cout<<"(stud.*p_fun)()"<<endl;
(stud.*p_fun)();//调用对象stud中的p_fun所指向的成员函数(即:stud.Print)
return 0;
}




this指针

每个对象中的数据成员都分别占用存储空间,如果对同一个类定义了n个对象,则有n组同样大小的空间一存放n个对象中的数据成员。
单数不同的对象都调用同一段函数代码段。
那么,当不同对象的成员函数引用数据成员时,怎么能保证引用的是所制定的对象的数据成员呢?
实际上,在每一个成员函数中,都包含一个特殊的指针,这个指针的名字是固定的,称为this指针。
它是指向本类对象的指针,它的值是当前被调用的成员函数所在的对象的起始地址。

例如:
Print()函数中

	cout<<num<<"\t"<<score<<endl;

实际上是

	cout<<this->num<<"\t"<<this->score<<endl;

this指针式隐式使用的,它是作为参数被传递给成员函数。

在程序中的函数:
void Student::Print(){
cout<<num<<"\t"<<score<<endl;
}

C++编译系统会自动处理成:

void Student::Print(Student *this){
cout<<this->num<<"\t"<<this->score<<endl;
}

即在成员函数的形参表列中增加一个this指针。在调用成员函数stud.Print()时,实际上是用以下方式调用的:

stud.Print(&stud);


C++中的对象指针的更多相关文章

  1. C++中的智能指针、轻量级指针、强弱指针学习笔记

    一.智能指针学习总结 1.一个非const引用无法指向一个临时变量,但是const引用是可以的! 2.C++中的delete和C中的free()类似,delete NULL不会报"doubl ...

  2. C++中的函数指针和函数对象总结

    篇一.函数指针函数指针:是指向函数的指针变量,在C编译时,每一个函数都有一个入口地址,那么这个指向这个函数的函数指针便指向这个地址.函数指针的用途是很大的,主要有两个作用:用作调用函数和做函数的参数. ...

  3. vue中computed计算属性与methods对象中的this指针

    this 指针问题 methods与computed中的this指针 应该指向的是它们自己,可是为什么this指针却可以访问data对象中的成员呢? 因为new Vue对象实例化后data中的成员和c ...

  4. C# CLR via 对象内存中堆的存储【类型对象指针、同步块索引】

    最近在看书,看到了对象在内存中的存储方式. 讲到了对象存储在内存堆中,分配的空间除了类型对象的成员所需的内存量,还有额外的成员(类型对象指针. 同步块索引 ),看到这个我就有点不懂了,不知道类型对象指 ...

  5. 【转】vector中对象指针的排序

    原文:http://blog.csdn.net/tanlijun37/article/details/1948493 vector中对象指针的排序,初步想法是1: 把对象指针存到vector,重载bo ...

  6. java 对象变量 c++对象指针 初始化对象变量的2中方法

    java 对象变量 c++对象指针 java null引用 c++ null指针 Date deadline  是 对象变量,它可以引用Date类型的对象,但它不是一个对象,实际上它也没有引用对象. ...

  7. 获得函数返回值类型、参数tuple、成员函数指针中的对象类型

    //function_traits.h,获得函数返回值类型.参数tuple.成员函数指针中的对象类型 //参考https://github.com/qicosmos/cosmos/blob/maste ...

  8. 浅谈Java中的对象和引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  9. QT中使用函数指针

    想仿命令行,所以定义了一个类,让一个String 对应一个 function,将两者输入list容器. 类中定义了 QString commandStr; void (MainWindow::*com ...

随机推荐

  1. 采用xml的方式保存数据

    package com.example.myxmlmake; import java.io.File; import java.io.FileOutputStream; import java.uti ...

  2. 03-Foundation中NSMutableArray遍历、复制和排序

    目录: 一.NSString补充 二.NSMutableArray可变数组 三.遍历 四.NSArray支持的新语法 五.数组复制 六.数组的排序 SDK.API.Foundation.Cocoa是什 ...

  3. 教程:查找内存泄漏 (JavaScript)

    本主题带领您完成使用 JavaScript 内存分析器确定并修复简单内存问题的过程.在本教程中,我们创建一个生成大量数据的应用程序.我们预期在导航到新页时该应用程序会释放数据.  说明 JavaScr ...

  4. ios内存管理2-对象之间的内存管理

    同之前一样,新建一个基于命令行的工程,在新建一个Student类和一个Book类 编写如下代码: Student.h // // Student.h // 内存管理2-对象之间的内存管理 // // ...

  5. 使用BAT方法结束进程

    @echo off taskkill /f /im GAM.exe taskkill /f /im GCL10.exe http://www.cnblogs.com/FKdelphi/p/501540 ...

  6. QString与中文,QString与std::wstring的相互转换(使用fromStdWString和u8关键字)

    Qt版本:5.5.1 Qt的QString功能丰富,对非英语语言的支持也不是问题,但支持得不够直接.例如,像 ? 1 QString str("死亡使者赛维"); 这样直接用带中文 ...

  7. 基于visual Studio2013解决C语言竞赛题之1033数字交换

          题目 解决代码及点评 /* 功能:将一个一维数组中的偶数依次交换.例如有8个元素, 若其中第1.4.5三元素是偶数时应按下图交换. 例子: a[]={2,3,1,6 ...

  8. codeforces 148D 概率DP

    题意: 原来袋子里有w仅仅白鼠和b仅仅黑鼠 龙和王妃轮流从袋子里抓老鼠. 谁先抓到白色老师谁就赢. 王妃每次抓一仅仅老鼠,龙每次抓完一仅仅老鼠之后会有一仅仅老鼠跑出来. 每次抓老鼠和跑出来的老鼠都是随 ...

  9. zoj 1134 - Strategic Game

    题目:给你一棵树.找到最小的顶点集合,使得全部的边至少有一个顶点在这个集合中. 分析:树形dp,图论,最小顶点覆盖. 方案1:树形dp.分别记录每一个节点取和不取的最优解f(k.0)与f(k,1): ...

  10. 开发环境FAQ

    问: Win7下VS2008无法识别WinCE5.0SDK 答:拷贝WinXP环境(安装过VS2008 + WinCE5.0SDK)下C:/Program Files/Microsoft Visual ...