- 类是C++的核心特性;
- 类中的数据和方法成为类的成员;
- 类成员函数:
a. 定义在类内部的函数;可操作类的任意对象,可用访问对象中的所有成员;
b. 成员函数可定义在类内部,也可使用范围解析运算符::来定义;
c. 类定义中定义的成员函数把函数声明为内联的,即使没有使用inline关键字; - 类访问修饰符:public/private/protected
a. 数据封装是OOP的一个重要特点。防止函数直接访问类类型的内部成员;
b. public成员是类的外部可访问,无需使用成员函数来获取或设置公有变量的值;
c. private成员,在类的外部不可访问,不可查看。只有类和友元函数可用访问私有成员;
d. 默认类的所有成员是私有的;
e. 实际操作中,一般在私有区域定义数据,公有区域定于函数;
f. protected成员变量或函数与private十分相似,only,protected成员在派生类中可访问; - 继承中的特点:
a. public继承
基类成员属性 public protected private
派生类属性 public protected private
b. protected继承
基类成员属性 public protected private
派生类属性 protected protected private
c. private继承
基类成员属性 public protected private
派生类属性 private private private
-
private成员只能被类内成员和友元访问,不能被派生类访问;
-
protected成员可用被派生类访问;
-
类的构造函数,
a. 是类的一种特殊的成员函数,在每次创建类的新对象时执行;
b. 构造函数的名称与类的名称完全相同,并且不会返回任何类型,也不会返回void。
c. 可用于为某些成员函数设置初始值;
d. 默认的构造函数无任何参数;也可有参数来初始化某些成员变量; -
类的析构函数
a. 在每次删除所创建的对象时执行;
b. 析构函数名称与类的名称完全相同,only, 前面加了个~,不会返回任何值,不能带有参数;
c. 有助于跳出程序前释放资源; -
拷贝构造函数
a. 是一种特殊的构造函数,在创建对象时,使用同一类中之前创建的对象来初始化新创建的对象;
i. 通过使用另一个同类型的对象来初始化新创建的对象;
ii. 复制对象把它作为参数传递给函数?
iii. 复制对象,并从函数返回这个对象;
iv. 如果类中没有定义拷贝构造函数,编译器会自行定义一个;
v. 如果类带有指针变量,并有动态内存分配,则它必须有个拷贝构造函数和一个赋值操作符? -
原因:C++会自动给没有定义赋值操作符的类生成一个缺省的操作符函数(逐位拷贝,进行赋值);
-
造成内存泄漏;
-
造成指针指向非法空间;
-
友元函数
a. 定义在类外部,但有权访问类的所有私有成员和保护成员;
b. 友元函数的原型在类的定义中出现过,但它不是类的成员函数;
c. 友元可以是一个函数,也可以是一个类;
d. 声明函数为类的友元,在函数原型前使用friend; -
内联函数
a. 内联函数通常与类一起使用;
b. 如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方;
c. 对内联函数做任何修改,都需要重新编译函数的所有客户端;
d. 内联关键字inline;
e. 如果已定义的函数多于一行,编译器会忽略inline;
f. 在类中定义的函数都是内联函数,即使没有inline说明符; -
C++中的this指针
a. 每个对象都能通过this指针来访问自己的地址;
b. this指针是所有成员函数的隐含参数;
c. 友元函数没有this指针,因为友元不是类的成员;
d. 只有成员函数才有this指针;
e. 类的静态成员函数不能访问this指针; -
指向类的指针
a. 指向类的指针与指向结构的指针类似;
b. 指向类的指针的成员,需要使用成员访问运算符->;
c. 所有的指针,在使用之前,都必须初始化; -
类的静态成员
a. 使用static修饰类成员为静态成员;
b. 当声明类的成员为静态时,无论创建多少个类的对象,静态成员都只有一个副本;
c. 静态成员在所有类的对象中是共享的;
d. 所有的静态数据默认初始化为0;
e. 不能把静态成员的初始化放在类的定义中;
f. 在类外,使用范围解析运算符::来重新声明静态变量并初始化它; -
静态成员函数
a. 如果把函数成员声明为静态,就可以把函数与类的任何特定对象独立开来;
b. 静态函数,在类对象不存在的情况下,也能被调用;
c. 静态函数只需使用类名::就可访问;
d. 静态成员函数只能访问静态成员数据/其他静态成员函数/类外部的其他函数;
e. 静态成员函数有类范围,它们不能访问类的this指针; -
静态成员函数与普通成员函数的区别
a. 静态成员函数没有this指针,只能访问静态成员;
b. 普通成员函数有this指针,可以访问类中的任意成员; -
继承是OOP另一个最重要的概念。
-
一个类可以派生自多个类,它可以从多个基类继承数据和函数;
-
使用一个类派生列表来指定基类,类派生列表以一个或多个基类命名;
-
继承的三个方式:public/protected/private(默认方式)。
-
派生类可以访问基类中所有非私有成员,因此如果基类成员不想被派生类的成员函数访问,则应在基类中声明为private。
-
一个派生类继承了所有的基类方法,以下情况除外:
a. 基类的构造函数/析构函数/拷贝构造函数;
b. 基类的重载运算符;
c. 基类的友元函数; -
多继承:一个子类可有多个父类,继承多个父类的特性;
-
C++允许在同一作用域中的某个函数和运算符指定多个定义,分别成为函数重载和运算符重载;
-
重载声明:一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但参数列表和定义不同;
-
当调用一个重载函数或重载运算符时,编译器通过把使用的参数类型和定义中的参数类型相比较,选用最合适的定义。
-
选择最合适的重载函数或重载运算符的过程,成为重载决策;
-
同一作用域内,可以声明几个功能类似的同名函数,其形参列表必须不同;
-
大部分的C++内置的运算符都可以被重载或重定义。
-
重载的运算符是带有特殊名称的函数,函数名是 operator+(要重载的运算符符号)。与其他函数一样,重载运算符要有一个返回类型和形参列表。
-
当类之间存在层次结构,且类之间是通过继承关联时,就会用到多态。
-
C++多态:调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
-
每个子类都有一个基类某函数(是虚函数)的独立实现,这就是多态。
-
虚函数是基类中使用virtual声明的函数;
-
派生类中重新定义基类中的虚函数时,会让编译器不要静态链接(编译时前期绑定)到该函数。
-
在程序中任一点,根据所调用的对象类型,来选择调用的函数,这种操作被成为(运行时)动态链接,或后期绑定。
-
纯虚函数:在基类中没有对虚函数给出定义(函数没有主体)的函数。虚函数=0;
-
数据抽象:只向外界提供关键信息,并隐藏其后台实现细节;
-
数据抽象依赖于接口与实现分离;
-
C++中,使用类来自定义抽象数据类型(ADT abstract data type);
-
数据抽象的好处:
a. 类的内部收到保护;
b. 类实现可以随着时间推移而发生变化,以应对不断变化的需求; -
任何带有公有和私有成员的类都可以作为数据抽象的实例。
-
抽象把代码分离为接口与实现。在设计组件时,必须保持接口独立于实现,这样,如果底层实现改变了,接口保持不变。
-
数据封装:OOP编程中,把数据和操作数据的函数绑定在一起的概念。引申出另一个OOP的重要概念——数据隐藏。
-
数据封装和数据抽象
a. 数据封装是把数据和操作数据的函数绑定在一起的机制;
b. 数据抽象是一种将实现与接口分离的机制。 -
默认情况下,类中定义的所有item都是私有的。这是实现封装的一种方式。
-
把一个类定义为另一个类的友元类,会暴露实现细节,降低封装性。理想的做法是尽可能对外隐藏每一个类的实现细节。
-
为了保证良好的封装性,通常将类成员状态设置为private,适用于所有成员,包括虚函数。
-
接口描述了类的行为和功能,不需要完成类的特定实现。
-
C++接口是使用抽象类来实现。
-
抽象类是类中至少有一个纯虚函数的类,数据抽象是实现与接口分离的概念。
-
纯虚函数:通过声明虚函数=0;
-
抽象类(ABC abstract basic class)是为了给其他类提供一个可以继承的合适的基类,抽象类不能被用于实例化对象,只能用作接口。
-
不要试图实例化一个抽象类。
-
如果一个ABC的子类需要被实例化,则必须实现每一个虚函数,也就是说,C++支持使用ABC声明接口。
-
如果派生类中没有重写纯虚函数,就试图实例化该类的对象,会发生编译错误。
-
可用于实例化对象的类是具体类。
更多学习资料,请关注下面的公众号:不定期分享
深度学习网络总结
机器学习算法及其应用场景
算法与数据结构(leetcode 题解)
cuda编程与并行优化
其他读书分享如:《战国策》,《智囊全集》
宇宙常识科普与星座辨别
等等