首页 > 其他分享 >第26节 对象的定义和使用

第26节 对象的定义和使用

时间:2024-07-01 09:58:46浏览次数:3  
标签:26 定义 对象 Data 成员 函数 data 指针

第26节 对象的定义和使用

1.对象的的定义及 对象的动态建立和释放
1、对象的的定义
►定义一个类时,也就是定义了一个具体的数据类型。若要使用类,需要将类实例化,即定义该类
的对象。 
►需要注意,我们之前也使用了“对象”一词,那里主要是指数据对象。 
►从现在起,“对象”一词专门表示类的实体。

►1.先定义类类型再定义对象 
►有两种定义对象的形式: 
	►①将类的名字直接用作类型名:
		类名 对象名列表;
	►②指定关键字class或struct,后面跟着类的名字:
        class  类名 对象名列表; 
	    或
        struct 类名 对象名列表;
►对象名列表是一个或多个对象的序列,各对象之间用逗号(,)分隔,最后必须用分号(;)结
束,对象取名必须遵循标识符的命名规则。例如:
    Point a,b; //C++特色定义对象 
    class Point x,y; //兼容C语言特色定义对象

►2.定义类类型的同时定义对象 
    ►一般形式为:
        class 类名 { //类体 
            成员列表 
        } 对象名列表;
	►例如:
        class Point { //类体 
        public: …//公有的数据成员和成员函数 
        private: …//私有的数据成员和成员函数 
        } one , two; //对象列表

►3.直接定义对象 
    ►一般形式为:
    	class { //类体 
            成员列表 
        } 对象名列表;
    ►例如:
        class { //无类名类体
        public: …//公有的数据成员和成员函数 
        private: …//私有的数据成员和成员函数 
        } p1 , p2; //对象列表
►一般而言,定义类型时不进行存储空间的分配 。 
►当定义一个对象时,将为其分配存储空间 。
►有时人们希望在需要用到对象时才创建(create)对象,在不需要用该对象时就撤销(destroy)
它,释放其所占的存储空间,从而提高存储空间的利用率。 
►利用new运算符可以动态地分配对象空间,delete运算符释放对象空间。
2、对象的动态建立和释放
►动态分配对象的一般形式为:
    类名 * 对象指针变量; 
	对象指针变量 = new 类名;
►例如:
    Point *p; //定义指向Point对象的指针变量 
    p = new Point; //动态分配Point对象

	►用new运算动态分配得到的对象是无名的,它返回一个指向新对象的指针的值,即分配得到是
	对象的内存单元的起始地址。程序通过这个地址可以间接访问这个对象,因此需要定义一个指
	向类的对象的指针变量来存放该地址。显然,用new建立的动态对象是通过指 针来引用的。 
    ►在执行new运算时,如果内存不足,无法开辟所需的内存空间, C++编译器会返回一个0值指
    针。因此,只要检测返回值是否为0,就可以判断动态分配对象是否成功,只有指针有效时才
    能使用对象指针。
        
►当不再需要使用由new建立的动态对象时,必须用delete运算予以撤销。例如: 
    delete p; //撤销p所指向的Point对象 
►释放了p所指向的对象。此后程序不能再使用该对象。 
►请注意,new建立的动态对象不会自动被撤销,即使程序运行结束也是如此,必须人为使
用delete撤销。 
【例26.1】
    1 #include<iostream> 
    2 using namespace std; 
    3 class Box 
    4 { public: 
    5 	int width, length, height; 
    6 }; 
    7 int main() 
    8 { 
    9 	Box * p=new Box; 
   10 	p->width=10; p->length=20; p->height=30; 
   11 	cout<<p->width<<"\t"<<p->length<<"\t"<<p->height<<endl; 
   12 	delete p; 
   13 	return 0; 
   14 }
2.对象成员的引用、对象的赋值、对象的指针
3、对象成员的引用
►访问对象中的成员可以有3种方法: 
    ►①通过对象名和对象成员引用运算符(.)访问对象中的成员; 
    ►②通过指向对象的指针和指针成员引用运算符(->)访问对象中的成员; 
    ►③通过对象的引用变量和对象成员引用运算符(.)访问对象中的成员;
    
►1.通过对象名访问对象中的成员 
    ►访问对象中数据成员的一般形式为:对象名.成员名
    ►调用对象中成员函数的一般形式为:对象名.成员函数(实参列表)
    ►需要注意,从类外部只能访问类公有的成员。
    
►例如已定义一个类:
    class Data { //Data类 
    public:
        int data; 
        void fun(int a,int b,int d); 
    private: 
        void add(int m) { data+=m; } 
        int x,y; 
        …… 
    };
►则函数
	void caller1() 
	{ 
        Data A, B; //定义对象 
        A.fun(1,2,3); //正确,类外部可以访问类的public成员函数 
        A.data=100; //正确,类外部可以访问类的public数据成员 
        A.add(5); //错误,类外部不能访问类任何private的成员 
        A.x=A.y=1; //错误,类外部不能访问类任何private的成员 
        B.data=101; //正确,A.data和B.data是两个对象的数据成员,为不同的存储空间 
        B.fun(4,5,6); //正确,A.fun和B.fun函数调用相同的代码,但作用不同的数据成员 
	}

►2.通过对象指针访问对象中的成员
    ►访问对象中数据成员的一般形式为: 对象指针—>成员名 
    ►调用对象中成员函数的一般形式为: 对象指针—>成员函数(实参列表)

►则函数
    void caller1() 
	{ 
        Data A, &r=A; //定义对象引用变量 
        r.data=100; //正确,类外部可以访问类的public数据成员 
        r.fun(1,2,3); //正确,类外部可以访问类的public成员函数 
    }
4、对象的赋值
►如果一个类定义了两个或多个对象,则这些同类的对象之间可以互相赋值。这里所指的对象的“值”
是指对象中所有数据成员的值。 
►对象赋值的一般形式为: 对象名1=对象名2 
►注意对象名1和对象名2必须属于同一个类。
    
►关于对象赋值的说明: 
    ►(1)对象的赋值只对其中的非静态数据成员赋值,而不对成员函数赋值。 
    ►(2)如果对象的数据成员中包括动态分配资源的指针,按上述赋值的原理,赋值时只复制
    了指针值而没有复制指针所指向的内容。
5、对象、对象指针或对象引用作为函数的参数和返回值
►函数的参数可以是对象、对象指针或对象引用。 
    ►(1)当形参是对象时,实参要求是相同类的对象名,C++不能对类对象进行任何隐式类型
    转换。此时形参是实参对象的副本。 
        ►采用这样的值传递方式会增加函数调用在空间、时间上的开销,特别是当数据成员的
        长度很大时,开销会急剧增加。 
        ►实际编程中,传递对象时需要考虑类的规模带来的调用开销,如果开销很大时建议不
        用对象作为函数参数。 
	
    ►(2)当形参是对象指针时,实参要求是同类对象的指针,C++不 能对对象指针进行任何
    隐式类型转换。 
    	►函数调用时,无论类多大规模,传递的参数是一个地址值,其开销非常小。 
    	►采用地址传递方式,在函数中若按间接引用方式修改了形参对象本质上就是修改实
    	参对象。因此,使用对象指针作为函数参数可以向主调函数传回变化后的对象。
    
    ►(3)当形参是对象引用时,实参要求是同类的对象,其功能与对象指针相似。 
    	►此时函数形参对象实际上是实参对象的别名,为同一个对象。在函数中若修改了形参
    	对象本质上就是修改实参对象。因此,使用对象引用作为函数参数可以向主调函数传回
    	变化后的对象。
【例26.2】
    1 #include <iostream> 
    2 using namespace std; 
    3 void func1(Data a,Data *p,Data &r) 
    4 { 
    5 	a.data=100; p->data=200; r.data=300; 
    6 } 
    7 int main() 
    8 { 
    9 	Data A, B, C; 
    10 	A.fun(1,2,3); B.fun(4,5,6); C.fun(7,8,9); 
    11 	func1(A,&B,C);//将对象A、B的地址、对象C的引用传递到函数func1 
    12 	return 0; 
    13 }
►如果不希望在函数中修改实参对象的值,函数形参可以作const限定,例如:                                           
    void func2(Data a,const Data *p,const Data &r) 
    { 
        a.data=100; 
        p->data=200; //错误,左值是const对象 
        r.data=300; //错误,左值是const对象 
    }                                                                                                 
►不必对对象形参作const限定,如上述代码中的形参a,因为即使在函数中修改了a,也不会影响
实参对象。                             
►函数返回值可以是对象、对象指针或对象引用。 
    ►函数返回对象时,将其内存单元的所有内容复制到一个临时对象中。因此函数返回对象时会
    增加调用开销。 
    ►函数返回对象指针或引用,本质上返回的是对象的地址而不是它的存储内容,因此不要返回
    局部对象的指针或引用,因为它在函数返回后是无效的。
►例:
    Data func1() 
    { 	Data a; a.fun(1,2,3); 
     	return a; //可以返回局部对象,它被复制返回 
    }
    Data* func2(Data *p1,Data *p2) 
    { 	if (p1->data > p2->data) return p1; 
     	return p2; 
    }
    Data& func3(Data &r1,Data &r2) 
    { 	if (r1.data > r2.data) return r1; 
     	return r2; 
    }
	
	void caller() 
    { 
        Data A, B, C; 
        A.fun(1,2,3); 
        B.fun(4,5,6); 
        C=func1(); 
        func2(&A,&B)->data=100; //等价于 (&B)->data=100; 
        func3(A,B).data=100; //等价于 B.data=100; 
    }

►例:
    Data* func() 
    { 
        Data a; 
        Data *p=&a; 
        return p; //返回局部对象a的指针p 
    }
    void caller() 
    { 
        Data *p1; 
        p1=func(); 
        p1->data=100; //a已不存在,引用错误 
    }

标签:26,定义,对象,Data,成员,函数,data,指针
From: https://blog.csdn.net/m0_69088645/article/details/140092342

相关文章

  • 第25节 类的定义
    第25节类的定义1.定义类及成员的访问控制1、定义类►C语言——面向过程的程序设计思想►自顶向下,逐步求精;►一个main函数+若干子函数。►C++语言——面向对象的程序设计思想►实现软件设计的产业化;►自然界是由实体(对象)组成的;►(1)......
  • 53、Flink 测试工具测试用户自定义函数详解
    1.测试用户自定义函数a)单元测试无状态、无时间限制的UDF示例:无状态的MapFunction。publicclassIncrementMapFunctionimplementsMapFunction<Long,Long>{@OverridepublicLongmap(Longrecord)throwsException{returnrecord+1;}......
  • Cesium 实战 - 自定义纹理材质系列之 - 涟漪效果
    Cesium实战-自定义纹理材质系列之-涟漪效果核心代码完整代码在线示例Cesium给实体对象(Entity)提供了很多实用的样式,基本满足普通项目需求;但是作为WebGL引擎,肯定不够丰富,尤其是动态效果样式。对于实体对象(Entity),可以通过自定义材质,实现各种动态效果,虽......
  • 【Effective Python教程】(90个有效方法)笔记——第3章:函数——24:用None和docstring来描
    文章目录第3章:函数第24条用None和docstring来描述默认值会变的参数函数默认值的坑(函数的默认参数值只在定义函数时计算)解决方法:将函数默认参数值设为None,然后再在函数体中判断并初始化函数默认参数值设置为None的其他应用示例“函数默认参数值设置为None”与“函数参数......
  • 【简易版tinySTL】 红黑树- 定义, 插入, 构建
    文章目录旋转左旋右旋左旋右旋代码实现红黑树的基本性质红黑树的插入红黑树的插入示例红黑树修复代码实现参考资料旋转对于一个平衡二叉搜索树,左子树高度为4,右子树高度为2,它们的高度差为2,破坏了平衡性(高度差<2才算平衡,因此需要调整二叉树使其平衡)二叉树最基本的......
  • 对前端js高级面向对象的理解? 如何理解前端js中的内置对象、 对象原型、原型链?
    对象前言对象是一个包含相关数据和方法的集合(通常由一些变量和函数组成,我们称之为对象里面的属性和方法)对象是javascript中的一个重要的概念,甚至有“JavaScript中万物皆是对象”的说法。首先看面向对象 面向对象编程将一个系统抽象为许多对象的集合,每一个对象代表了这个系......
  • The this Pointer (this 指针) and An Array of Objects (对象数组)
    ThethisPointer[this指针]andAnArrayofObjects[对象数组]1.The`this`Pointer(`this`指针)2.AnArrayofObjects(对象数组)References1.ThethisPointer(this指针)classStock{private: doubletotal_val_; ...public: double......
  • PHP 面向对象编程(OOP)入门指南
    面向对象编程(Object-OrientedProgramming,简称OOP)是一种编程范式,通过使用对象来设计和组织代码。PHP作为一种广泛使用的服务器端脚本语言,支持面向对象编程。本文将介绍PHP面向对象编程的基本概念和用法,并提供示例代码帮助理解。一、面向对象编程的基本概念1.1类和对象......
  • 23201826-熊锋-第三次blog
    一.前言这两次pta作业第一次为家居强电电路模拟程序-3,这次题型,是在家居强电电路模拟程序-2的基础上进行迭代,虽然仅仅只增加了互斥开关等,但带来的改变同上一次十分巨大,通路的判断不再仅仅局限于各个控制设备0与1,而是要判断多个控制设备的开闭,其位置乃至互斥开关的实际情况,使得并联......
  • 揭秘Python:对象类型打印
    哈喽,大家好,我是木头左!一、Python数据类型简介在Python的世界中,了解你正在处理的数据类型是至关重要的。Python提供了多种内置数据类型,包括数字(整数和浮点数)、字符串、列表、元组、字典等。这些数据类型决定了你可以对数据执行哪些操作,以及如何高效地存储和处理数据。1.数字......