Cpp(26-A4303-13:00)
第一章、初始C++
namespace:可以自定义命名空间
匿名命名空间的作用是限制命名空间的内容仅能被当前源文件使用。
cin>>:输入,插入运算符
count<<:输出,提取运算符
endl;:换行
const:常变量
bool:逻辑类型,0或1
enum:枚举类型
new: 在堆上分配内存,并调用对象的构造函数来初始化对象。
delete: 释放由 new分配的内存,并调用对象的析构函数来销毁对象。
*
符号主要用于指针的声明和解引用。&
符号主要用于取地址和引用。
函数重载(overload)是指同一作用域内函数名相同但参数个数或者参数类型不同的函数。
C++的三大特点:
同时支持四种编程范式,面向过程、面向对象、泛型编程、函数式编程。
同C语言相比,适合开发大型应用程序。
具有可复用、可维护、可扩展、灵活性好的特点。
C++的泛型编程是通过模版实现的,该技术可以实现类型参数化。
“开闭原则”,是指对修改关闭,对增加;扩展开放。
在C++中,如有类型参数,则需要使用 尖括号<> 把类型参数括起来。
在编程语言的语法描述中(注意,不是说写代码的时候),如果某一部分是可选的,则应使用 方括号[] 括起来。
第二章、类与对象
构造函数:
对对象进行初始化,其中复制或拷贝构造函数就是用对象初始化新的对象。
若没有定义系统会提供一个默认的无参构造函数,默认的无参构造函数体也为空,不具有实际初始化意义。
自动隐式调用。
成员权限控制符一般设置为public。
当程序员没有显式的给出拷贝构造函数时,编译器提供默认拷贝构造函数。
默认拷贝构造函数是的运行方式是按位复制。
默认拷贝构造函数容易产生指针悬挂问题。
拷贝构造函数:具有构造函数特性,且使用本类对象的引用作为形参,能够通过已存在的对象初始化该类的另一个对象。
析构函数的功能是释放资源。
构造函数 | 析构函数 |
---|---|
与类同名 | 与类同名,前面加~ |
没有返回类型,void、return都不要 | 没有返回类型,void、return都不要 |
可以有参数,可以重载 | 没有参数,不能重载 |
通常为公有函数 | 基类的析构函数通常为虚析构函数 |
一个类可以有多个 | 一个类只有一个 |
友元常见的两种形式是友元函数和友元类。
友元函数(不是成员函数、破坏隐藏性,尽量少用、在类内声明,使用关键字friend、可以访问类中私有成员)
类:
类中定义的成员属性(访问范围从小到大):private(默认属性)、protected、public。
默认访问权限:struct(public)、class(private)
自身类对象不能作为类的成员。
类是相似特征的对象的抽象,对象是类的一个实例。
对象:
数据封装就是将一组数据和与这组数据有关操作组装在一起,形成一个实体,这个实体也就是对象。
面向对象编程(OOP)的三大特征分别是封装、继承和多态。它们各自的基本目的如下:
封装:基本目的是隐藏内部实现。
继承:基本目的是实现代码的重用。
多态:基本目的是改写对象行为。多态包括编译时多态(函数重载、运算符重载)和运行时多态(虚函数、抽象类),能够根据对象的实际类型来调用相应的方法,从而实现更加灵活的代码设计。
面向对象的三大设计原则:1.封装变化点 2.优先使用组合而非继承 3.针对抽象进行编程
过程:
- 面向过程编程的基本单位是函数。
指针:
静态成员函数没有this指针。
指针本身并不会分配或释放内存空间。
this指针(是隐藏的)会保证每个对象拥有自己的数据成员,但共享处理这些数据的代码。
一个函数功能不太复杂,但要求被频繁调用,则应把它定义为 内联函数。
公有的静态成员函数,可以通过对象或类名进行调用。
第三章、运算符重载
运算符重载是对已有的运算符重新进行定义,使其能够在程序员定义的类型上进行操作。本质是函数重载。
流输出运算符(<<)需要重载为全局函数,因为其左操作数的类型只能是ostream类型。
输入输出运算符应该重载为类的友元函数。
运算符按照全局函数方式进行重载,,不必声明为友元函数。
重载运算符由关键字operator和其后要重载的运算符共同组成。
单目运算符(单目运算符使用成员函数重载可以不用形参,双目运算符使用一个参数。)
递增和递减运算符:
++
和--
,用于分别增加或减少操作数的值。取地址和间接引用运算符:
&
和*
,分别用于获取变量的地址和访问指针所指向的值。正负号运算符:
+
和-
,用于表示数字的正负。逻辑非运算符:
!
,用于对布尔值进行取反操作。按位取反运算符:
~
,用于对二进制数进行按位取反操作。sizeof 运算符:
sizeof
,用于返回数据类型或变量所占内存的字节数。类型转换运算符:例如
(int)
,用于执行显式类型转换。
在C++中,只能使用成员函数重载的运算符有:=、()、[]、->
第四章、继承与派生
在派生类中基类的保护或者基类公有都可以直接访问,基类的私有成员只能由基类的成员函数来访问。
在公有继承的情况下,基类的公有或保护成员在派生类中的访问权限保持不变。
C++语言建立类族是通过类的继承,继承包括单继承和多继承。
派生类和基类的关系(多对多)也称为 “is-a” 关系。这种关系用来描述一个对象是另一个对象的一种特殊类型。例如,”鱼是一种动物” 。
继承被称为“is-a”关系,组合被称为“has-a”关系。
两个类即有相同的功能,也有不同的功能,则应该让这两个类派生自同一个基类,相同的功能写在基类,中,不同的功能写在派生类中。
在基类指针指向派生类对象时,基类指针代表抽象和稳定的,派生类对象代表具体和变化的。
无论采用什么样的继承方式,派生类包括基类的所有成员,包括私有成员,但不能直接访问私有成员。
公有继承对派生类继承成员的访问控制权限影响:
基类成员访问属性 | public | protected | private | 不可访问 |
---|---|---|---|---|
在派生类中的访问属性 | public | protected | 不可访问 | 不可访问 |
保护继承对派生类继承成员的访问控制权限影响:
基类成员访问属性 | public | protected | private | 不可访问 |
---|---|---|---|---|
在派生类中的访问属性 | protected | protected | 不可访问 | 不可访问 |
私有继承对派生类继承成员的访问控制权限影响:
基类成员访问属性 | public | protected | private | 不可访问 |
---|---|---|---|---|
在派生类中的访问属性 | private | private | 不可访问 | 不可访问 |
- 重载:同一作用域中函数名相同但参数列表不同。
- 隐藏:派生类中定义的同名函数隐藏了基类中的所有同名函数。
- 覆盖:派生类中定义的虚函数与基类中同名且参数列表相同的虚函数,覆盖基类实现,实现运行时多态性。
第五章、多态与虚函数
多态
多态实现需要满足的条件:
基类声明虚函数。
派生类重写基类的虚函数。
将基类指针指向派生类对象,通过基类指针访问虚函数。
多态是一种不同的对象调用名称相同的函数,却因上下文不同会有不同实现的一种机制。
多态有两种形式,分别是重载实现的静态多态和虚函数实现的动态多态。
虚函数
虚函数是基类中声明的函数,使用关键字 virtual
标记。虚函数可以在派生类中被重写,从而实现不同的行为。
声明虚函数需要注意:
构造函数不能声明为虚函数,析构函数可以。
虚函数不能是静态成员函数。
友元函数不能声明为虚函数,但虚函数可以作为另一个类的友元函数。
在C++中,实现动态多态的核心数据结构是一张虚函数表(Vtable)。
基类和派生类中拥有原型相同的成员函数,且基类指针指向派生类对象,通过基类指针调用该函数时,如果该函数是虚函数,则函数的调用取决于对象的类型;如果该函数不是虚函数,则函数调用取决于变量的类型。
纯虚函数是在基类中使用 = 0
声明的虚函数,没有函数体,必须在派生类中实现。拥有纯虚函数的类称为抽象类,无法直接创建该类的实例.
纯虚函数用于定义接口,确保所有派生类都实现这些函数,使基类成为抽象类,不能实例化。纯虚函数强制派生类提供具体实现,从而实现动态多态。
关键字override可以检测派生类对基类虚函数的重写是否正确。
C++的STL主要是通过模版编程实现的。