第三章 类与对象
3.1 类的声明和对象的定义
类是对象的抽象,对象是类的实例。
类成员的声明,包括数据成员和成员函数。
成员的可访问性分为3类:公用的(public)、受保护的(protected)、私有的(private)。
public: 既可以被本类的成员函数访问,也可以在类的作用域内被其他函数访问。
protected: 可以被本类及其派生类的成员函数访问,但不能被类外访问。
private: 只能被本类的成员函数访问而不能被类外访问(类的友元除外)。
struct默认public;class默认private
声明类时系统并不分配内存单元,而定义对象时系统会给每个对象分配内存单元,以存储对象的成员。
3.2 类的成员函数
类中有两类成员,一类是数据成员,用来描述对象的静态属性;另一类则是成员函数,用来描述对象的动态行为。
C++要求在类外定义成员函数时,在函数名的前面要加上类名和作用域运算符进行限定。
类的声明必须在成员函数定义之前。
inline成员函数?在编译时将被调用函数的代码直接嵌入到调用函数处。
C++为类的对象分配内存空间时只为对象的数据成员分配内存空间,而将对象的成员函数放在另外一个公共的区域,无论这个类声明多少个对象,这些对象的成员函数在内存中只保存一份。
对象所占空间大小取决于 对象的数据成员 ,与成员函数无关。
3.3 对象成员的访问
(1) 通过对象名和成员运算符来访问对象的成员。(访问属性必须为公用)
对象名.成员名 test1. Show( ); (2)通过指向对象的指针来访问对象的成员。
Test test1;
Test *pTest=&test1;
test1.Show();
pTest->Show();
(*pTest).Show()
(3) 通过对象的引用来访问对象的成员。
3.4 构造函数与析构函数
构造函数
构造函数是类的一个特殊成员函数,构造函数的作用是在创建对象时对对象的数据成员进行初始化。(不能在类内对数据成员进行初始化)
(1)构造函数名与类名相同,且没有返回值,定义构造函数时,在函数名前什么也不能加(加void也不可以)
(2)构造函数不需要用户调用,它是由系统在创建对象时自动调用的。构造函数要声明为public。
(3)C++系统在创建对象时必须执行一个构造函数,否则系统无法创建对象。用户自己没有定义构造函数,则C++系统会自动提供一个构造函数,称之为默认的构造函数, 这个构造函数没有函数体,没有参数,不能进行初始化操作。
构造函数重载:定义多个构造函数,这些构造函数具有相同的函数名(都与类名同名),而参数表中参数的个数或类型不同
析构函数 ~类名
析构函数:在系统释放对象占用的内存之前进行一些清理工作。
(1)没有返回值,void类型也不行
(2)没有参数,无法重载
(3)析构函数在对象生命周期结束时由系统自动调用。
(4)系统自动生成的析构函数没有函数体,不执行任何实际意义的清理工作
一个类可以有多个构造函数,但只能有一个析构函数。
先构造的后析构,后构造的先析构
当创建对象时调用构造函数,当释放对象时调用析构函数。
如果该类包含指向动态分配的内存的指针数据成员,则必须编写析构函数。
3.5 对象数组
Box boxs[3]= {10, 20,30};
Box boxs[3]= {
Box(1, 3, 5),
Box(),
Box(3,6, 9)
};
3.6 对象指针(通过指针只能访问公用的成员)
- 指向对象的指针
2. 指向对象成员的指针
(1)指向对象数据成员的指针
(2)指向对象成员函数的指针
3.7 对象与const
- 常对象
如果一个对象被声明为常对象,则不能调用该对象的非const型的成员函数。
//常对象中的数据成员为常变量且必须要有初始值。
const 类名 对象名[ (实参表)];
类名 const 对象名[(实参表)];
//const型成员函数:
float Volume () const;
- 常对象成员
常数据成员在初始化时必须使用构造函数的参数初始化表。
// 1.常数据成员
Box::Box(float L, float W, float H) : length (L)
{ width=W; height=H; }
// 2.常成员函数
返回值类型 成员函数名(形参表) const; //函数声明
返回值类型 所属类名::成员函数名(形参表) const //函数定义
在类的定义中,const型成员函数不能调用非const型成员函数。
- 指向对象的常指针
类名 * const 指针名 = &类的对象;
Box box(2,2, 2);
Box * const pbox = &box;
- 指向常对象的指针(常用于函数的形参)
const 类名 *指针名;
当希望在调用函数时对象的值不被修改,就应当把形参定义为**指向常对象的指针,**同时用对象的地址作实参。
- 对象的常引用
通过常引用只能调用对象的const型成员函数
const 类名 &引用名=对象名;
3.8 对象的动态创建与释放
如果内存分配成功,new运算符会返回分配的内存的首地址(声明一个指针变量来保存);
如果分配内存失败,则会返回一个NULL
delete 指针名; //释放指针所指对象
3.9 对象的赋值与复制
复制构造函数(复制构造函数的形参则只有一个,即本类对象的引用。 )
需要复制对象的情况:
①程序中需要新创建一个对象,并用另一个同类的对象对它初始化
②函数的参数是类的对象
③函数的返回值是类的对象
复制与赋值的不同点:
3.10 向函数传递对象
值传递(系统调用了复制构造函数)
地址传递、引用传递(系统只在创建str对象时调用构造函数,而在函数调用时没有再调用复制构造函数。)