Bootstrap

C++重要知识点总结(简答题,期末考试 面向对象难点 类和对象)精华在后面

期末考试时总结的一些知识点,希望能对大家有帮助。

一、C++语言基础

1,程序由语句组成,语句由基本要素(单词)组成

2,数组:具有相同类型数据的有序集合

3,C++语言没有提供字符串类型,字符串变量是作为一维字符数组来处理

​ 字符串是一个数组+可以通过指针使用数组==>通过指针使用字符串

​ char *ps=“Hello” 不安全:*ps可改变,字符串是常量,所以建议改为const char *ps=“Hello”

基本要素包括:
标识符(程序员定义,字母、数字、下划线,首位不能是数字)

关键字(C++编译器预定义,具有固定含义)、

变量(占内存,可以赋不同的值)、常量(不占内存)、

运算符(进行运算就是调用一个函数)、

表达式(由常量、变量、函数调用和运算符组成,每个表达式都将产生一个值)
面向对象及其程序设计的基本概念:

面向对象 = 对象 + 类 + 继承 + 消息

面向对象程序设计:把一个复杂的系统分解成多个功能独立对象(类),然后把这些对象组合起来,完成系统的功能。

对象:具有责任的实体

哪些是声明语句,执行语句?

声明语句:声明变量和函数的语句

执行语句:包括赋值语句、表达式语句、函数调用语句和流程控制语句等,通知计算机完成一定的操作

为什么要有变量的类型?可以没有吗?

不可以。(不同类型的变量在内存中占的空间大小不同,且编译器对不同类型的变量处理方式不同,只有知道变量类型,编译器才能为变量分配空间,并且对其进行操作处理)

变量块存的是地址即内存中的起点,变量类型决定地址的长度即内存块的终点,只有知道了内存块的起点和终点才能将内存块中的数据完整的取出来

数组的维数为什么要是常量表达式,可以是变量吗?

在预编译阶段编译器就会为该数组分配空间,如果无法确定数组大小则无法分配空间,所以必须是常量表达式

数据类型包括:

基本数据类型、指针类型和构造类型三大类。构造类型包括数组、结构和枚举等类型。

基本数据类型:number, string, boolean, null, undefined, symbol, Biglnt

(1)C++预定义的数据类型,包括字符型、整数型、实型(单精度和双精度)和空值型。

(2)每种基本数据类型都使用一个关键字来表示。

(3)类型修饰符:signed、unsigned、short、long

静态数据成员的作用

不破坏封装性,解决对象之间的通信,实现数据共享

声明:static <数据类型><静态成员名>
初始化时机:<数据类型><类名>::<静态数据成员名> = <初始值>

静态成员的访问:

通过对象访问:person::m_nCount

通过类名访问:CPerson::m_nCount

二、类和对象,继承与多态

(1)什么是对象

在计算机科学中,对象是系统中用来描述客观事物的一个实体,具有自己特定的属性和行为,是用来构成系统的一个基本单位,而系统可以看作是由一系列相互作用的对象组成,

(2)什么是类

类定义了同类对象的公共属性和行为,属性用数据结构表示,行为用函数表示。
可以用如下公式表示:
类 = 数据结构 + 对数据进行操作的函数

(3)对象和类的关系

对象是类的一个实例,因此对象和类的关系相当于元素与集合的关系、变量与变量的“数据类型”的关系。

内联函数存在的意义及弊端:

通过编译器预处理,在调用内联函数的地方将内联函数内的语句Copy到调用函数的地方,从而提高了效率,减少了一些不必要的开销。

使用内联函数后虽然调用函数的开销降低了,但内联函数会导致主函数指令增多、函数体积增大等情况。

常指针he常值变量指针:

常值变量指针:(可以指向常值变量或普通变量)

const int *p

指向常量的指针,不能通过常指针来改变所指对象的值,但常指针本身可以改变,可以指向另外的对象

常指针:(只能指向普通变量)

 int* const p

指针本身的地址不能被改变,但是它地址所指向的值可以改变
面向对象程序设计四个基本特征及其含义:

(1)抽象:对一类对象进行概括,抽出它们的共同特质并加以描述的过程,抽象的过程就是对问题进行分析和认识的过程

(2)封装:将抽象得到的属性数据和行为代码有机地结合,形成一个具有类特征的整体(避免了外部与对象的影响)

(3)继承:继承是指一个新类可以从已有的类派生而来,解决软件的重用问题。(新类继承了原有类的特性即属性和行为,新类还可以对原有类的行为进行修改,增加新的属性和行为)

(4)多态性:指类中具有相似功能的不同函数使用一个名称来实现,允许不同类的对象对同一消息作出不同的反应

编译时多态(静态多态):在函数名或运算符相同的情况下,编译器在编译阶段就能够根据函数参数类型的不同来确定要调用的函数—通过重载实现

运行时多态(动态多态):在函数名、函数参数和返回类型都相同的情况下,只能在程序运行时才能确定要调用的函数—通过虚函数实现、

为什么初始化成员变量不能在类定义的时候进行?如何初始化成员变量?

成员变量的值属于每一个具体的对象,类定义的时候无法确定成员变量的值属于哪一个对象。成员变量一般是是私有的,不能在类外被访问,所以通过类的构造函数进行初始化。

静态成员函数与成员、静态成员、成员变量、静态成员变量

一般的成员函数可以访问静态成员

静态成员函数只能访问静态成员和静态成员变量

命名空间及其意义:

(1)命名空间:是指标识符的各种可见范围,利用命名空间可以通过创建作用范围来对全局命名进行分割。

(2)如果没有命名空间,变量、函数和类都存在于同一个全局命名空间中,可能会由于同名问题而产生冲突

(3)本质上来讲,一个命名空间确定了一个命名空间作用域

(4)命名空间是对一些成员进行声明的一个描述性区域,在命名空间中声明的任何成员都会局限于该命名空间内

(5)如果命名空间中的成员在该命名空间外被使用,必须加上作用域限制符:: 例如std::

构造函数及其意义(没有返回类型):

构造函数:不需要函数调用语句,就能在创建对象时由系统自动调用。

作用:在对象被创建时使用特定的值去构造对象,使得在声明对象时就能自动地完成对象的初始化。

构造函数可以定义为虚函数吗?

不能,虚函数需要通过对应的虚指针vtable来调用,而这个虚指针是对象创建完毕才有的。

构造函数带默认参数的好处:

增强容错性,当用户忘记传参数或传参数的数量不足时,程序仍然会执行

析构函数及其意义(没有返回类型,不能有参数):

析构函数:在对象的生存周期即将结束时被系统自动调用。

作用:在对象被删除前做一些清理善工作和数据保存工作。

拷贝构造函数及其意义:

拷贝构造函数:用来完成基于对象的同一类其他对象的构造及其初始化。

只有一个函数参数:本类对象的引用(把一个已有对象的数据成员赋值给新创建的对象)

默认拷贝构造函数是浅拷贝,存在安全风险

浅拷贝:藕断丝连, 只进行基本数据类型的拷贝,两个对象的指针指向同一个地址,只拷贝了一个引用

深拷贝:恩断义绝,拷贝了对象所有属性,两者完全独立

B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。

调用拷贝构造函数的时机:

1.当用类的一个对象去初始化该类的另一个对象时系统自动调用拷贝构造函数实现赋值。

  1. 若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用拷贝构造函数。
  2. 当函数的返回值是类对象时,系统自动调用拷贝构造函数。
为什么基类的析构函数一定要定义为虚函数?

在实现多态时,当用基类操作派生类,保证先释放派生类再释放基类,防止只析构基类而不析构派生类造成内存泄露的状况发生。

【用基类指针去接收申请的包含派生类对象的空间,当这个指针完成任务之后,我们需要delete掉,防止内存泄漏,我们期望空间中的对象调用自己的析构函数,完成空间的释放,然后事实是程序只析构了基类,并没有析构派生类,造成了内存泄漏。】

在这里插入图片描述

纯虚函数和不能实例化的抽象类存在的必要性?

(含有纯虚函数的类称为抽象类,抽象类不能实例化)

有时在基类中无法给出基类中虚函数的实现代码,只是需要提供一个接口等待派生类具体描述其行为

虚基类的含义及作用:

虚基类是一种派生方式,用来解决多重多级继承造成的二义性问题,保证派生类只有一个基类对象(例如类B和类C继承于类A,如果类D同时继承类B和类C,类E的一个对象里面包含两个基类A的对象 ==》将B和C的继承方式改为虚继承,将D里A的对象统一为一个,只有一个基类A对象)

虚基类的构造函数只能被调用一次,由最派生类调用

为什么要进行运算符的重载?

解决类对象之间的运算,让编译器在遇到对象运算时能按我们要求的进行运算,使代码更为简洁优美,增加代码可读性

基类和派生类:

(1)为什么基类指针指向派生类对象时,只能调用派生类从基类继承的公有成员,不能访问新增的成员?
基类指针和派生类对象的地址在内存空间所占的长度不一样,当使用基类指针指向派生类对象时,它的地址与派生类对象首地址相同,但地址在内存空间的长度没有发生改变,仍然只含有基类成员的部分。
解决方法:
1.通过虚函数,可以调用派生类成员(声明虚函数,意味着该成员函数在派生类中可能被重新定义)
2.强制转换为派生类指针

(2)为什么强制将基类指针转化为派生类指针后可以访问派生类对象的成员?
基类指针强制转化为派生类指针,值没有变化,变化的只有数据类型,即指针类型从基类指针变成派生类指针,内存的首地址没有发生变化,变成可以访问整个派生类对象的成员

(3)为什么派生类指针不能指向基类对象?

基类对象只能访问基类对象的内存空间,当用派生类指针指向基类对象的时候,相当于拓展了基类对象指针所能访问的空间,会访问到基类的外部,不安全。

;