c++基础复习

目录

一.基础语言

1.说一下static关键字的作用(隐藏、变量内容的持久、默认初始化为0、类的静态成员变量和函数)

2.c++和c的区别

3.c++中指针和引用的区别

4.c++中指针和数组的区别

5.野指针是什么

6.请说出const与#define 相比,有何优点

7.c++中析构函数的作用

8.C语言是如何进行函数调用的

二.面向对象

1.面向对象的三个基本特征

2.C++析构函数为什么要为虚函数

3.请你说一下c++类成员中的访问权限

4.请你说一下静态函数和虚函数的区别

5.请你说一下重载和覆盖

6.请说一下你理解的虚函数和多态

三.容器和算法

1.STL的map和set是怎么实现的,有什么区别

四.编译与底层

1.c++源文件从文本到可执行文件的过程

2.c++如何实现内存管理

3.什么情况下会发生段错误

五.c++11特性

1.c++11新特性


一.基础语言

1.说一下static关键字的作用(隐藏、变量内容的持久、默认初始化为0、类的静态成员变量和函数)

(1)全局静态变量

    在全局变量前加关键字static,全局变量就定义为一个全局静态变量。

  • 静态存储区:在整个程序运行期间一直存在
  • 初始化:未经初始化的全局静态变量会自动初始化为0
  • 作用域:全局静态变量在声明他的文件之外是不可见的,准确的说是从定义之处开始,到文件结尾。

(2)局部静态变量

    在局部变量前加关键字static,局部变量就定义为一个局部静态变量。

  • 内存中的位置:静态存储区
  • 初始化:未经初始化的局部静态变量会自动初始化为0
  • 作用域:作用域还是局部作用域,当定义它的函数或者语句块结束的时候,作用域结束。但是当局部静态变量离开作用域后,并没有销毁,而是继续驻留在内存中,只不过我们不能再对其就行访问,直到该函数再次被调用,并且值不变。

(3)静态函数

     在函数声明前加static,函数被定义为静态函数。函数的定义和声明默认情况下都是extern,但是静态函数只在声明他的文件中可见,不能被其他文件使用。在多个文件中可以定义同名的函数,不会引起冲突。

(4)类的静态成员变量

     在类中,静态成员可以实现多个对象之间的共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性。因此,静态成员是所有对象共享的成员,而不是每个对象的成员。对多个对象来说,静态数据成员只存储一处,供所有对象公用。

(5)类的静态成员函数

     静态成员函数在实现过程中不能直接引用类中声明的非静态成员,可以引用类中声明的静态成员(*)。如果静态成员函数中要引用非静态成员时,可通过对象来引用。

2.c++和c的区别

    设计思想上,c++是面向对象的语言,而c是面向过程的结构化编程语言。

  • 语法上,c++具有重载、继承和多态的三大特性。
  • c++相比c,增加许多类型安全的功能,比如强制类型转换。
  • c++支持范式编程,比如模板类,函数模板等。

3.c++中指针和引用的区别

引用:引用就是某个目标变量的别名,对应用的操作和对变量直接操作效果完全相同。声明一个引用的时候,一定要对其初始化。声明了一个引用,不是新定义了一个变量,它只表示该引用名是目标变量的一个别名,他本身不是一个数据类型,因此引用本身不占存储单元,系统也不会给他分配存储单元。不能建立数组的引用。

指针:指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。

区别:

  1. 指针有自己的一块空间,而引用只是一个别名
  2. 引用必须被初始化,但是指针不用
  3. 不存在指向空值的引用,但存在指向空值的指针
  4. 引用初始化以后不能被修改,但是指针可以改变所指的对象

4.c++中指针和数组的区别

                          指针                           数组
保存数据的地址保存数据

直接访问数据,首先获得指针的内容,然后将其作为地址,从该地址中提取数据

直接访问数据
通常用于动态的数据结构通常用于固定数目且数据类型相同的元素
通过Malloc分配内存,free释放内存

隐式的分配和删除

通过指向匿名数据,操作匿名函数自身即为数据名

 

5.野指针是什么

    野指针就是指向一个已删除的对象或者未申请访问受限内存区域的指针。

6.请说出const与#define 相比,有何优点

    const作用:定义常量、修饰函数参数、修饰函数返回值三个作用。被Const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。

   1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。

   2) 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。

   const存放区域:全局对象:静态存储区    局部对象:存放在栈区     字面值常量:常量存储区

7.c++中析构函数的作用

    析构函数和构造函数对应,当对象结束其生命周期后,如对象所在的函数已经调用完毕后,系统会自动执行析构函数。

    如果没有编写析构函数,编译系统会自动生成一个缺省的析构函数(即使自定义了一个析构函数,编译器也总会给我们合成一个析构函数,那么系统将会先调用自定义的析构函数在调用自动合成的析构函数),它并不进行任何操作。

    如果一个类中有指针,并且使用过程中动态申请了内存,那么最好用显示的析构函数在销毁类之前,释放掉申请的内存空间,避免内存泄漏。

     类析构顺序:派生类-->对象成员-->基类(与构造函数相反

8.C语言是如何进行函数调用的

      每一个函数调用都会分配函数栈,在栈内进行函数执行过程。调用前,先把返回地址压栈,然后把当前函数的esp指针压栈。

二.面向对象

1.面向对象的三个基本特征

封装、继承、多态

其中,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!

 

封装:就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。封装是面向对象的特征之一,是对象和类概念的主要特性。 简单的说,一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。

继承:是指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力;

多态:意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。

具体分析见大佬文章(清晰易懂、里边包含很多问题):https://blog.csdn.net/qq_39755395/article/details/79751362

2.C++析构函数为什么要为虚函数

上述大佬文章里有代码分析

   在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类的状况发生。

   基类指针可以指向派生类的对象(多态性),如果删除该指针delete []p;就会调用该指针指向的派生类析构函数,而派生类的析构函数又自动调用基类的析构函数,这样整个派生类的对象完全被释放。如果析构函数不被声明成虚函数,则编译器实施静态绑定,在删除基类指针时,只会调用基类的析构函数而不调用派生类析构函数,这样就会造成派生类对象析构不完全。所以,将析构函数声明为虚函数是十分必要的。

3.请你说一下c++类成员中的访问权限

     继承方式有三种:public、protect、private, 总的来说,父类成员的访问限定符通过继承派生到子类中之后,访问限定符的权限小于、等于原权限。其中,父类中的private成员只有父类本身及其友元可以访问,通过其他方式都不能进行访问,当然就包括继承。protected多用于继承当中,如果对父类成员的要求是——子类可访问而外部不可访问则可以选择protected继承方式。public子类中可以访问,外部也可以访问。

4.请你说一下静态函数和虚函数的区别

     静态函数在编译的时候就已经确定了运行时机,虚函数在运行的时候动态绑定。虚函数因为用了虚函数表机制,调用的时候要增加一次内存开销。

5.请你说一下重载和覆盖

重载:一个类中两个函数名相同,但是参数列表不同(个数、类型),返回值类型没有要求,在同一作用域

重写(覆盖):子类继承了父类,父类中的函数是虚函数,在子类中重新定义了这个虚函数。

6.请说一下你理解的虚函数和多态

        多态的实现主要分为静态多态和动态多态,静态多态主要是重载,在编译的时候就已经确定:动态多态是用虚函数机制实现的,在运行期间动态绑定。举个例子:一个父类类型的指针指向一个子类对象时候,使用父类的指针去调用子类中重写了的父类中的虚函数的时候,会调用子类重写过后的函数,在父类中声明为加了virtual关键字的函数,在子类中重写时候不需要加virtual也是虚函数。
       虚函数的实现:在有虚函数的类中,类的最开始部分是一个虚函数表的指针,这个指针指向一个虚函数表,表中放了虚函数的地址,实际的虚函数在代码段(. text)中。当子类继承了父类的时候也会继承其虚函数表,当子类重写父类中虚函数时候,会将其继承到的虚函数表中的地址替换为重新写的函数地址。使用了虚函数,会增加访问内存开销,降低效率。

三.容器和算法

1.STL的map和set是怎么实现的,有什么区别

map(红黑树) unordered_map(哈希表)

红黑树数据结构再讨论

四.编译与底层

1.c++源文件从文本到可执行文件的过程

2.c++如何实现内存管理

3.什么情况下会发生段错误

五.c++11特性

1.c++11新特性

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值