第四章 类与对象
面向对象程序设计的基本特点
- 封装:就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏,只通过外部接口访问类
- 继承:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
实现继承:是指直接使用基类的属性和方法而无需额外编码的能力;
接口继承:是指仅使用属性和方法的名称、但是子类必须提供实现的能力。 - 多态:同一名称,不同功能,达到行为标志统一,多态机制使具有不同内部结构的对象可以共享相同的外部接口。基于虚函数和虚继承
public:公有成员,任何外部函数都可以访问公有类型的数据和函数
private:私有成员,只允许本类中的函数访问,以及友元,不写关键字默认定义为私有成员
protected:保护成员,与私有成员类似,在继承与派生时有区别
构造函数
与类同名,无返回值
class Clock{
public:
Clock(int newH,int newM, int newS);
void setTime(newH,int newM, int newS);
void showTime();
private:
int hour;minute,second;
};
Clock::Clock(int newH,int newM, int newS) //构造函数实现
{
hour(newH);minute(newM),second(newS); //直接使用列表初始化
}
复制构造函数:用于当用一个对象去赋值给新对象
有三种情况会调用复制构造函数
- 一个对象以值传递的方式传入函数体
- 一个对象以值传递的方式从函数体返回
- 一个对象需要通过另一个对象进行初始化
复制构造函数参数类型必须是本类对象的引用且加const限定,const用于使用避免引用过程中可能会对原实参的修改,意思是,只能使用这个引用来读取对象的数据,而不能使用这个引用来修改对象
浅拷贝和深拷贝
浅拷贝只是增加了一个指针指向被拷贝的对象,会造成两个问题:
1.改变拷贝的对象被拷贝的对象也会改变
2.析构拷贝的对象时会释放分配的内存,析构被拷贝的对象时会将这块已经被释放过的内存再释放一次而导致出错
深拷贝是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。在对含有指针成员的对象进行拷贝时,必须要自己定义拷贝构造函数,使拷贝后的对象指针成员有自己的内存空间,即进行深拷贝,这样就避免了内存泄漏发生
4.类的组合
类的组合构造函数形式:
类名::类名(对象成员所需的形参,本类成员形参)
:对象1(参数),对象2(参数),…
{
//函数体其他语句
}
类的组合构造函数,Line类的私有数据成员为两个Point类变量p1和p2
Line::Line(Point xp1, Point xp2) : p1(xp1), p2(xp2) {
// 表示xp1赋值给p1,xp2给p2,p1和p1为Line类中定义好的私有Point类变量
cout << "Calling constructor of Line" << endl;
double x = static_cast<double>(p1.getX() - p2.getX());
double y = static_cast<double>(p1.getY() - p2.getY());
len = sqrt(x * x + y * y);
}
类的复制构造函数
Line::Line (Line &l): p1(l.p1), p2(l.p2) {//组合类的复制构造函数
cout << "Calling the copy constructor of Line" << endl;
len = l.len;
}
5.前向引用声明:在类的定义前引用该类,常见于两个类的相互引用
6.UML:三个部分 事务 关系 图
7.结构体和联合体
结构体:和类相似,用于很多数据而较少函数的情况,类似于数据库
联合体:所有成员公用内存单元,任何两个成员不会同时有效,例如成绩的三种记录方式:等级制、是否合格、分数制
8.枚举类:
语法形式:
emun class 枚举类型名:低层类型{枚举值列表};