《第10章 对象和类》

目录

 

10.1 过程性编程和面对对象编程

10.2 抽象和类

10.2.1 类型是什么

10.2.2 C++中的类

10.2.3 实现类成员函数

10.2.4 实用类

10.2.5 小结

10.3 类的构造函数和析构函数

10.3.1 声明和定义构造函数

10.3.2 使用构造函数

10.3.3 默认构造函数

10.3.4 析构函数

10.3.5 改进Stock类

10.3.6 构造函数和析构函数小结

10.4 this指针

10.5 对象数组

10.6 接口和实现小结

10.7 类作用域

10.8 抽象数据类型


10.1 过程性编程和面对对象编程

  1. 最重要的OOP特性:抽象;封装和数据隐藏;多态;继承;代码的可重用性。
  2. 采用OOP方法时,首先从用户的角度考虑对象。

10.2 抽象和类

10.2.1 类型是什么

  1. 在C++中,用户定义类型指的是实现抽象对象的类设计。
  2. 指定基本类型完成了三项工作:决定数据对象需要的内存数量;决定如何解释内存中的位;决定可使用数据对象执行的操作或方法。

10.2.2 C++中的类

  1. 类是一种将抽象转换为用户定义类型的C++工具,它将数据表示和操纵数据的方法组合成一个整洁的包。
  2. 类规范由两个部分组成:类声明(以数据成员的方式描述数据部分,以成员函数的方式描述公有接口);类方法定义(描述如何实现类成员函数)。
  3. 一个约定俗成的约定:将类名首字母大写。
  4. 成员函数可以就地定义,也可以用原型定义。
  5. 关键字private和public描述了对类成员的访问控制,使用类对象的程序都可以直接访问公有部分,但只能通过公有成员函数来访问对象的私有成员。
  6. 数据项通常放在私有部分,组成类接口的成员函数放在公有部分。
  7. 不必在类声明中使用关键字private,因为这是类对象的默认访问控制。
  8. 类和结构的区别:结构的默认访问类型是public,而类为private。通常使用类来实现类描述,而把结构限制为只表示纯粹的数据对象或没有私有部分的类。

10.2.3 实现类成员函数

  1. 类成员函数两个特殊的特征:定义成员函数时,使用作用域解析操作符来识别函数所属的类;类方法可以访问类的private部件。
  2. 类作用域。限定名;非限定名。
  3. 最好的方法:将类声明放在头文件中,而将类成员函数定义放在单独的一个源代码文件中。
  4. 何时将某个函数声明为私有成员函数???
  5. 其定义位于类声明中的函数都将自动成为内联函数,类声明常将短小的成员函数作为内联函数。也可以在类声明之外定义成员函数,并使其成为内联函数,只需在类实现部分中定义函数时使用inine限定符即可。
  6. 调用成员函数时,它将使用被用来调用它的对象的成员函数。
  7. 所创建的每个新对象都有自己的存储空间,用于存储其内部变量和类成员;但同一个类的所有对象共享同一组类方法,即每种方法只有一个副本。

10.2.4 使用类

  1. C++的目标是使得使用类与使用基本的内置类型尽可能相同。
  2. 客户/服务器模型

10.2.5 小结

  1. 公有部分的内容构成了设计的抽象部分-公有接口。
  2. 在类声明和类方法之外使用该名称时,需要使用作用域解析操作符进行限定。

10.3 类的构造函数和析构函数

10.3.1 声明和定义构造函数

  1. 类构造函数,专门用于构造新对象,将值赋给它们的数据成员。
  2. 构造函数的原型和函数头都有一个有趣的特征,虽然没有返回值,但没有被声明为void类型,实际上,构造函数没有声明类型。
  3. 程序声明构造函数时,将自动调用构造函数。
  4. 构造函数的参数表示的不是类成员,而是赋给类成员的值,因此,参数名不能与类成员相同。为避免这种混乱,通常的做法是在数据成员名中使用m_前缀。

10.3.2 使用构造函数

  1. 显式调用构造函数 Stock food = Stock("World Cabbage", 250, 1.25);
  2. 隐式调用构造函数 Stock food("World Cabbage", 250, 1.25);
  3. 无法使用对象来调用构造函数,因为在构造函数构造出对象之前,对象是不存在的,因此构造函数被用来创建对象,而不能通过对象来调用。

10.3.3 默认构造函数

  1. 默认构造函数是在未提供显式的初始化值时,被用来创建对象的构造函数。
  2. 默认构造函数没有参数,因为声明中不包含值。
  3. 如果要创建对象,而不显式地初始化,则必须定义一个不接受任何参数的默认构造函数。
  4. 定义默认构造函数的方式有两种,一种是给已有构造函数的所有参数提供默认值,另一种方式是通过函数重载来定义另一个构造函数。

10.3.4 析构函数

  1. 如果构造函数使用new来分配内存,则析构函数将使用delete来释放这些内存,如果没有使用new,只需让编译器生成一个什么都不做的隐式析构函数即可。
  2. 析构函数没有返回值和声明类型,析构函数没有参数。
  3. 由于在类对象过期时析构函数将自动被调用,因此必须有一个析构函数,如果程序员没有提供析构函数,编译器将隐式地声明一个默认析构函数,并在发现导致对象被删除的代码后,提供默认构造函数的定义。

10.3.5 改进Stock类

10.3.6 构造函数和析构函数小结

  1. 如果构造函数只有一个参数,则将对象初始化为一个与参数的类型相同的值时,该构造函数将被调用。
  2. 对于未被初始化的对象,程序将使用默认构造函数来创建。

10.4 this指针

  1. 每个成员函数(包括构造函数和析构函数)都有一个this指针。this指针指向调用对象。如果方法需要引用整个调用对象,则可以使用表达式*this。在函数的括号后面使用const限定符将this限定为const,这样将不能使用this来修改对象的值。
  2. 一般来说,所有的类方法都将this指针设置为调用它的对象的地址。
  3. 因为这个对象作为函数参数传递,所以显式地访问;因为这个对象调用类成员函数,所以隐式地访问。
  4. const Stock & topval ( const Stock & s ) const;该函数隐式地访问一个对象,而显式地访问另一个对象,并返回其中一个对象的引用。括号中的const表明,该函数不会修改被显式地访问的对象;而括号后的const表明,该函数不会修改被隐式地访问的对象。由于该函数返回了两个const对象之一的引用,因此返回类型也应为const引用。

10.5 对象数组

  1. 当程序创建未被显式初始化的类对象时,总是调用默认构造函数。
  2. 可以用构造函数来初始化数组元素,在这种情况下,必须为每个元素调用构造函数;如果类包含多个构造函数,则可以对不同的元素使用不同的构造函数。
  3. 初始化对象数组的方案是,首先使用默认构造函数创建数组元素,然后花括号中的构造函数将创建临时对象,然后将临时对象的内容复制到相应的元素中。因此,要创建类对象数组,则这个类必须有默认构造函数。

10.6 接口和实现小结

  1. 类接口:公有???
  2. 修改类的私有部分和实现文件属于实现变更;修改类的公有部分属于接口变更。实现变更改变了类的内部工作原理,接口变更改变了使用类的人可用的编码方式。

10.7 类作用域

  1. 类作用域意味着不能从外部直接访问类的成员,公有成员函数也是如此。也就是说,要调用公有成员函数,必须通过对象。
  2. 作用域为整个类的常量:第一种方式是在类中声明一个枚举(用这种方式声明枚举并不会创建类数据成员,所有对象中都不包含枚举);另一种方式是使用关键字static,用此方法创建的静态常量将与其他静态变量存储在一起,而不是存储在对象中,只能使用这种技术声明值为整数或枚举的静态常量,而不能存储double常量。

10.8 抽象数据类型

  1. ADT以通用的方式描述数据类型,而没有引入语言或实现细节。
  2. 类概念非常适合于ADT方法。
  3. 仔细选择数据类型,使类最小。
  4. 类很适合用于描述ADT。公有成员函数接口提供了ADT描述的服务,类的私有部分和类方法的代码提供了实现,这些实现对类的客户隐藏。

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值