程序设计 第六章 类和对象知识总结
面向对象系统由一组交互的对象构成,每个对象都有属于自己的属性和行为,这些对象通过相互之间的消息传递来写作实现系统的功能。对象所属的类型称为类,类是对一组具有相同属性和行为的对象的抽象。本章讨论C++中的类和对象。
类的基本思想是数据抽象和封装,数据抽象是一种依赖接口和实现分离编程的技术。类的接口包括用户包括用户能执行的操作,类的实现则包括类的数据成员,负责接口实现的函数体及定义类所需的各种私有函数。
类的定义:
类要实现数据抽象和封装,需要先定义一个抽象数据类型(ADT),包括一组数据和对这些数据的操作。最常见的方式是采用结构体加全局函数。
注意:类定义和结构体定义一样,要在最后加上;(分号)
class是 C++ 中新增的关键字,专门用来定义类。Student是类的名称;类名的首字母一般大写,以和其他的标识符区分开。
类只是一个模板,编译后不占用内存空间,所以在定义类时不能对成员变量进行初始化,因为没有地方存储数据。只有在创建对象以后才会给成员变量分配内存,这个时候就可以赋值了。
访问限定符:
public(共有);private(私有);protected(保护)
访问限定符说明:
1. public成员在类外可以直接访问;
2. protected和private成员在类外不能够访问
3. 它们的作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
4. class定义的类体中如果没有定义限定符,则默认访问权限是private;struct默认为为public型
类成员函数的 this 指针:
1. 每个成员函数都有一个指针形参,它的名字是固定的,称为this指针,this指针是隐式的
2. 编译器会对成员函数进行处理,在对象调用成员函数时,对象地址作实参传递给成员函数的第一个形参this指 针
3.this指针是成员函数隐含指针形参,是编译器自己处理的,我们不能在成员函数的形参中添加this指针的参数,定义时,也不能在调用时显示传递对象的地址给this指针
- this指针是一个常量,含有当前试试调用的对象的地址。不能改变this指针的值
例如:class X{
Int m;//数据成员m
public:
void setval(int m)//形参m
{
this->m=m//第一个m为当前对象的数据成员 第二个m为作用范围的对象
. . . . . .
. . . . . .
友元:
友元机制允许一个类将对其非公有成员的访问权授予指定的函数或类。
友元可以出现在类定义的内部的任何地方。
友元不是授予友元关系的那个类的成员,所以它们不受声明出现部分的访问控制影响。
一个类的友元可以是全局函数,另一个类的成员函数或另一个类。类A是类B的友元隐含着A的所有成员函数都是B的友元。但是不可传递。
建议:将友元声明成组地放在类定义的开始或结尾。
一般情况下友元会破坏类的封装性,因此,应该尽量避免使用友元。老师建议当运算符重载时再使用友元,其他地方不允许使用。
构造函数:
二 构造函数
构造函数时至少写俩,一个带参,一个不带参,解决说明对象时没有给实参的问题。
定义:
①类名(对象名)
②类名 对象名(实参列表)
构造函数是特殊的成员函数,用来保证每个对象的数据成员具有合适的初始值。
构造函数名字与类名相同,不能指定返回类型(也不能定义返回类型为void),可以有0-n个形参。
在创建类的对象时,编译器就运行一个构造函数。
1 构造函数可以重载
可以为一个类声明的构造函数的数量没有限制,只要每个构造函数的形参表是唯一的。
2 构造函数自动执行
只要创建该类型的一个对象,编译器就运行一个构造函数
3 构造函数初始化式
与其他函数一样,构造函数具有名字、形参表和函数体。
与其他函数不同的是,构造函数可以包含一个构造函数初始化列表
※构造函数初始化列表中的初始值的先后关系不会影响实际的初始化顺序
委托构造函数:
C++11扩展了构造函数初始化列表的功能,可以定义所谓的委托构造函数。
委托构造函数有一个成员初始化列表和一个函数体。成员初始化列表只有唯一一项,即类名本身。类名后面紧跟着圆括号括起来的参数列表,参数列表必须与类中另一个构造函数相匹配。
当一个构造函数委托给另一个构造函数时,收委托的构造函数的初始化列表和函数体依次执行,然后将控制权交还给委托者的函数体。
析构函数:
负责在对象生存期结束时返回相关资源和自动释放资源,当对象离开作用域时,或者用delete释放在堆上创建的对象时,析构函数都会被自动调用。
析构函数的名字时类名字前面加波浪线“~”。析构函数没有返回类型,也灭有任何参数。析构函数不能重载,只能为一个类定义唯一一个析构函数。例如:
//为账户类加上析构函数
calss Account{
Public:
//...
~Account();//析构函数
private:
...
};
类中的const成员:
类中的const成员会被分配空间的
类中的const成员的本质是只读变量
类中的const成员只能在初始化列表中指定初始值 (引用数据成员也是)
编译器无法直接得到const成员的初始值,因此无法进入符号表成为真正意义上的常量。
const对象:
const关键字能够修饰对象
const修饰的对象为只读对象
只读对象的成员变量不允许被改变
只读对象是编译阶段的概念,运行时无效
const成员函数:
const对象只能调用const的成员函数
const成员函数中只能调用const成员函数
const成员函数中不能直接改写成员变量的值
const成员函数的定义:Type ClassName::function(Type p) const
类中的函数声明与实际函数定义中都必须带const关键字。
五 static 类成员
static成员,有全局对象的作用,但又不破坏封装。
static成员变量:
static数据成员是与类关联的对象,并不与该类的对象相关联。
static输入==属于整个类,不专属于某个特定对象。
使用static成员而不是全局对象有三个优点:
(1)static成员的名字是在类的作用域中,因此可以避免与其他类的成员或全局对象名字冲突。
(2)可以实施封装。static 成员可以是私有成员,而全局对象不可以。
(3)通过阅读程序容易看出 static 成员是与特定类关联的,这种可见性可清晰地显示程序员的意图。
static成员函数:
在类的内部声明函数时需要添加static关键字,但是在类外部定义函数时就不需要了。
因为static成员是类的组成部分但不是任何对象的组成部分,所以有以下几个特点:
(1)static函数没有this指针
(2)static成员函数不能被声明为const(将成员函数声明为const就是承诺不会修改该函数所属的对象)
(3) static 成员函数也不能被声明为虚函数
(4)静态成员函数的地址可用普通函数指针储存,而普通成员函数地址需要用 类成员函数指针来储存。
static数据成员:
static 数据成员可以声明为任意类型,可以是常量、引用、数组、类类型,等等。
static 数据成员必须在类定义体的外部定义(正好一次),并且应该在定义时进行初始化。