C++类和对象的使用之对象指针
类和对象的使用之对象指针
对象指针的一般概念
对象指针:指向类的成员的指针。在C++中,可以说明指向类的数据成员和成员函数的指针。
对象指针遵循一般变量指针的各种规则:类名 *对象指针名;
对象指针名*成员名;
对象指针在使用之前,也一定要先进行初始化,让它指向一个已经声明过的对象,然后再使用。通过对象指针,可以访问到所指向对象的公有成员。
指向对像的指针
在建立对像时,编译系统会为每一个对像分配一定的存储空间,以存放其成员,对像空间的起始地址就是
对像的指针。可以定义一个指针变量,用来存和对像的指针。如果有一个类:
class Time
{public:int hour;int minute;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 就是指向Time类对象的指针变量,它指向对象t1。
定义指向类对象的指针变量的一般形式为:
类名 *对象指针名;
可以通过对象指针访问对象和对象的成员。如:
*pt pt所指向的对像,即t1
(*pt).hour pt所指向的对象中的hour成员,即t1.hour
pt->get_time() pt把指向的对象中的get_time函数,即t1.get_time()
(*pt).get_time()
指向对象成员的指针
a.指向对象数据成员的指针
定义指向对象数据成员的指针的方法与定主指向变通的指针变量的方法相同。如:
int *p;
定义指向对象数据成员的指针变量的一般形式为:
数据类型名 *指针变量名;
b.指向对象成员函数的指针
定义指向对象成员函数的指针变量的方法和定义指向变通函数的指针变量方法有所不同。
定义指向变通函数的指针变量的方法:
数据类型名 (*指针变量名)();如:
void (*p)();//p是指向void型函的指针变量
定义指向成员函的指针:
数据类型名 (类名::*指针变量名)();
使指针变量指向一个公用成员函数的一般形式为
指针变量名=&类名::成员函数名;
示例:
1 #include <iostream>2 using namespace std;3 class Time4 {5 public:6 Time(int ,int ,int );7 int hour;8 int minute;9 int sec;
10 void get_time();
11 };
12 Time::Time(int h,int m,int s)
13 {
14 hour = h;
15 minute= m;
16 sec = s;
17 }
18 void Time::get_time()
19 {
20 cout << hour << ":" << minute << ":" << sec << endl;
21 }
22
23 int main()
24 {
25 Time t1(10,13,56); //定义Time类对象t1
26 int *p1=&t1.hour;//定义指向整型数据的指针变量p1,并使p1指向t1.hour
27 cout << *p1 << endl;
28 t1.get_time();//调用对象t1的成员函数get_time()
29
30 Time *p2=&t1;//定义指向Time类对象的指针变量p2,并使p2指向t1
31 p2->get_time();//调用p2所指向对象的get_time()函数
32 void (Time::*p3)();//定义指向Time类公用成员函数get_time
33 p3 = &Time::get_time;//使p3指向Time类公用成员函数get_time
34 (t1.*p3)();//调用对象t1中p3所指的成员函数
35
36 return 0;
37 }
4、指向类的非静态成员的指针(非指向对象,而是指向对象成员)
指向对象成员的指针使用前也要先声明,再赋值,然后引用,因此首先要声明指向该对象所在类的成员的指针。注意,通过指向成员的指针也只能访问到公有成员。
语法形式:
类型说明符 类名::*指针名; //声明指向公有数据成员的指针类型说明符 (类名::*指针名)(参数表);//声明指向公有函数成员的指针
对数据成员指针赋值:
指针名 = &类名::数据成员;
此时还不能通过指针访问变量。类的声明只确定了各个数据成员的类型、所占内存大小以及它们的相对位置,在声明时并不为数据成员分配具体的地址。因此经上述赋值之后,只是说明了被赋值的成员指针式专门用于指向哪个数据成员的,同时在指针中存放该数据成员在类中的相对位置,当然通过这样的指针现在并不能访问什么。
由于类是通过对象而实例化的,在声明类的对象时才会为具体的对象分配内存空间,这时只要将对象在内存中的起始地址与成员指针中存放的相对偏移结合起来就可以访问到对象的数据成员了。
语法形式:对象名.*类成员指针名或 对象指针名à*类成员指针名成员函数指针赋值:指针名 = 类名::函数成员名;经过上述对成员函数指针赋值之后,还不能用指针直接调用成员函数,而是需要首先声明类的对象,因为必须要通过对象来调用非静态成员函数。利用指针调用成员函数:(对象名.*类成员指针名)(参数表)或 (对象指针名à*类成员指针名)(参数表)
5、指向类的静态成员的指针
类的静态成员可以用普通的指针来指向和访问。/**形式上把静态成员看成普通变量就可以**/
对象指针:在C++中,可以说明指向类的数据成员和成员函数的指针。
1. 对象指针作函数的参数
使用对象指针作为函数参数要经使用对象作函数参数更普遍一些。因为使用对象指针作函数参数有如下两点好处:
实现传址调用。可在被调用函数中改变调用函数的参数对象的值,实现函数之间的信息传递。
使用对象指针实参仅将对象的地址值传给形参,而不进行副本的拷贝,这样可以提高运行效率,减少时空开销。
当形参是指向对象指针时,调用函数的对应实参应该是某个对象的地址值,一般使用&后加对象名。 下面举一例子说明对象指针作函数参数。
1 #include <iostream.h>2 class M3 {4 public:5 M() { x=y=0; }6 M(int i, int j) { x=i; y=j; }7 void copy(M *m);8 void setxy(int i, int j) { x=i; y=j; }9 void print() { cout<<x<<","<<y<<endl; }
10 private:
11 int x, y;
12 };
13
14 void M::copy(M *m)
15 {
16 x=m->x;
17 y=m->y;
18 }
19
20 void fun(M m1, M *m2);
21 void main()
22 {
23 M p(5, 7), q;
24 q.copy(&p);
25 fun(p, &q);
26 p.print();
27 q.print();
28 }
29
30 void fun(M m1, M *m2)
31 {
32 m1.setxy(12, 15);
33 m2->setxy(22,25);
34 }
35
36 输出结果为:
37 5,7
38 22,25
从输出结果可以看出,当在被调用函数fun中,改变了对象的数据成员值[m1.setxy(12, 15)]和指向对象指针的数据成员值[m2->setxy(22, 25)]以后,可以看到只有指向对象指针作参数所指向的对象被改变了,而另一个对象作参数,形参对象值改变了,可实参对象值并没有改变。因此输出上述结果。
2. 对象引用作函数参数
在实际中,使用对象引用作函数参数要比使用对象指针作函数更普遍,这是因为使用对象引用作函数参数具有用对象指针作函数参数的优点,而用对象引用作函数参数将更简单,更直接。所以,在C++编程中,人们喜欢用对象引用作函数参数。现举一例子说明对象引用作函数参数的格式。
1 #include <iostream.h>2 class M3 {4 public:5 M() { x=y=0; }6 M(int i, int j) { x=i; y=j; }7 void copy(M &m);8 void setxy(int i, int j) { x=i; y=j; }9 void print() {cout<<x<<","<<y<<endl; }
10 private:
11 int x, y;
12 };
13
14 void M::copy(M &m)
15 {
16 x=m.x;
17 x=m.y;
18 }
19
20 void fun(M m1, M &m2);
21
22 void main()
23 {
24 M p(5, 7), q;
25 q.copy(p);
26 fun(p, q);
27 p.print();
28 q.print();
29 }
30
31 void fun(M m1, M &m2)
32 {
33 m1.setxy(12, 15);
34 m2.setxy(22, 25);
35 }
该例子与上面的例子输出相同的结果,只是调用时的参数不一样。
3.this指针
this指针是一个隐含于每一个类的成员函数中的特殊指针,它用于指向正在被成员函数操作的对象。实际过程是,当通过一个对象调用成员函数时,系统先将该对象的地址赋给this指针,然后调用成员函数,成员函数对对象的数据成员进行操作时,就隐含使用了this指针。/难怪:在成员函数之外无法访问数据成员,找不到对象呀!(当然中间的private,protected另作谈论/
当对一个对象调用成员函数时,编译程序先将对象的地址赋给this指针,然后调用成员函数,每次成员函数存取数据成员时,由隐含作用this指针。而通常不去显式地使用this指针来引用数据成员。同样也可以使用*this来标识调用该成员函数的对象。下面举一例子说明this指针的应用。
1 #include <iostream.h>2 class A3 {4 public:5 A() { a=b=0; }6 A(int i, int j) { a=i; b=j; }7 void copy(A &aa); //对象引用作函数参数8 void print() {cout<<a<<","<<b<<endl; }9 private:
10 int a, b;
11 };
12
13 void A::copy(A &aa)
14 {
15 if (this == &aa) return; //这个this是操作该成员函数的对象的地址,在这里是对象a1的地址
16 *this = aa; //*this是操作该成员函数的对象,在这里是对象a1。
17 //此语句是对象aa赋给a1,也就是aa具有的数据成员的值赋给a1的数据成员
18 }
19
20 void main()
21 {
22 A a1, a2(3, 4);
23 a1.copy(a2);
24 a1.print();
25 }
C++类和对象的使用之对象指针相关推荐
- java查看对象锁级别_对象级别锁 vs 类级别锁(Java)
前言 对于多线程(并发)和Spring Boot这两块在同步进行学习中,在看到使用synchronized关键字使操作同步时,看到和C#中不一样的东西,所以这里呢,就深入学习了下,若有错误之处,还望指 ...
- python里面的类和对象_Python中类和对象在内存中是如何保存?
类以及类中的方法在内存中只有一份,而根据类创建的每一个对象都在内存中需要存一份,大致如下图: 如上图所示,根据类创建对象时,对象中除了封装 name 和 age 的值之外,还会保存一个类对象指针,该值 ...
- python里的类与一切事物都是对象
对于python,一切事物都是对象,对象基于类创建 列如 name='csdcs' li=[1,3,43] 上面两个都是对象,因为它们都是python中的 类里面存着许多的功能,功能的集合, ...
- 从JVM看类的加载过程与对象实例化过程
一. 类的加载过程 1. 类的加载过程大致是个什么过程? 我们编写产生.java文件,这些.java文件经过Java编译器编译成拓展名为.class的文件,.class文件中保存着Java代码经转换后 ...
- java对象生命周期_Java对象生命周期和类生命周期
原标题:Java对象生命周期和类生命周期 作者:彭空空 链接:https://www.jianshu.com/p/25ea857ba78b 导读 对象的生命周期 类的加载机制 类的生命周期 类加载器 ...
- Python 的类其实是一个特殊的对象
Python 中的类是一个特殊的对象. Python 中一切皆对象: class AAA:定义的类属于类对象. obj1 = AAA(): 属于实例对象. 在程序运行时,类同样会被加载到内存,类是一个 ...
- java类放到对象_Java中类和对象总结
一.面向对象概述 1.1 对象:世界万物皆对象. 类:同一类事物的统称,是这类对象的统称.类就是对象的设计图. 例:面向对象解决大雁南飞. 1.抽出对象--大雁 2.识别对象的属性--静态属性(翅膀. ...
- 关于jQuery对象(类数组对象)以及DOM对象相互转化问题——[object Object]和[object HTMLInputElement]
之前在某官网课程上看有关jQuery和bootstrap的相关教程,有一节课是教我们如何制作价格菜单的按钮以及总价问题 选中按钮,按钮样式会发生变化,右上角价格会自动运算 6个菜单的html结构差不多 ...
- [工具库]JOJSONBuilder工具类——一键把多个bean对象数据转换为JSON格式数据
本人大四即将毕业的准程序员(JavaSE.JavaEE.android等)一枚,小项目也做过一点,于是乎一时兴起就写了一些工具. 我会在本博客中陆续发布一些平时可能会用到的工具. 代码质量可能不是很好 ...
- C++远征之封装篇——类和封装、实例化和对象成员访问
一.封装篇的学习内容 数据成员 成员函数 构造函数 析构函数 对象复制 对象赋值 对象数组 对象指针 this指针 二.类与封装 三.实例化和对象成员访问 (1)从栈中实例化对象 (2)从堆中 ...
最新文章
- 解析equals(Object obj)和compareTo(T obj)
- 自适应游标共享技术01(Adaptive Cursor Sharing)
- android jni研究
- 摘要注释_《间架结构摘要九十二法》高清图片+注释 爱书法的朋友值得收藏
- linux python2.7安装教程_Linux中RedHat下安装Python2.7开发环境的详细教程-学派吧-
- 注册中心—组件—Consul
- 通向架构师的道路(第七天)之漫谈使用ThreadLocal改进你的层次的划分
- 真香系列-JSFinder实用改造
- 记2个月来,我在Csdn 掀起的微软面试风暴
- 如何部署Java_web项目到云服务器上
- 8.Kubernetes Service(服务)
- 三张图看懂 clientheight、offsetheight、scrollheight
- android revre view,MK802 4.0.4 CWM Recovery
- 【ARM】Linux驱动移植
- chainlink2022年春季编程马拉松
- sklearn.LabelEncoder解决未见过值问题ValueError y contains previously unseen labels [69]
- AI虚拟人物 数字人直播,不用出镜,不用露脸的直播方式(附教程 软件)
- 《尚硅谷30天入门Java》学习笔记1
- 牛顿迭代法 matlab程序
- 小米路由器登录服务器无响应是怎么回事,小米路由器登录界面打不开怎么办? | 192路由网...
热门文章
- 重载是什么?只有返回值类型不同算不算重载?为什么?
- uniapp苹果无法上架_uni-app 打包ios上架app store流程
- android mp3 lrc歌词文件utf-8歌词显示为乱码,百度歌词显示乱码 LRC歌词批量转换 UTF-8编码批量转换为GB或ANSI 文本编码批量转换...
- oracle 判断重复次数,sql 查询 某字段 重复次数 最多的记录
- kubeadm搭建的K8S集群升级
- 什么是海外调查问卷?都有哪些形式
- Excel一键知道文本的字符长度
- 电商大数据日志收集系统之EFK
- python实现zigzag_Zigzag Iterator的Pythonic方式?
- 程序员自我修养——提问的智慧