前言:
  考研复试面试时经常会问到一些编程语言的基础知识,尤其C++面向对象这一块,为了避免会用不会说的情况,本文作为个人笔记精炼的语言梳理了复试面试常考察的知识点(后附高频面试题),个人这块概念知识比较薄弱,复试前保下命ヾ(◍°∇°◍)ノ゙

参考资料

   C++教程|菜鸟教程
   网络上各位大牛的博文

C++简介

C++是什么?

C++ 是一种 静态类型的、 编译式的编程语言,支持 过程化编程、 面向对象编程。
(静态类型的编程语言是在编译时执行类型检查,而不是在运行时执行类型检查。)

引入目的是什么?

面向对象是相对于面向过程来讲的,它把 数据和方法组织为一个整体来看待,更像事物的本身的运行模式。

三个组成

核心语言:所有构件块,包括变量、数据类型和常量等。
C++ 标准库:提供了大量的函数,用于操作文件、字符串等。
标准模板库(STL):提供了大量的方法,用于操作数据结构等。

四大特性(重点考察点)

封装
继承
多态
抽象
(问三大特性,回答前三个即可)

C++程序

C++程序是什么?

C++ 程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。

基本语法包括哪几类?

对象:对象具有 状态行为。如:某一只白色的正在叫唤的猫。对象是类的实例。
:描述对象行为/状态的 模板。如:这一类白色正在叫唤的猫;
方法:从基本上说, 一个方法表示一种行为。一个类可以包含多个方法。
即时变量 :每个对象都有其独特的即时变量。对象的状态是由这些即时变量的值创建的。

C++存储类

存储类是什么?

存储类定义C++程序中变量/函数的 可见范围生命周期

重要的几种存储类

auto
static
extern

auto存储类

用于两种情况:
1.声明变量时根据初始化表达式 自动推断该变量的类型
2.声明函数时函数返回值的占位符。

static存储类

使用 static 修饰局部变量可以在函数调用之间 保持局部变量的值,而不需要在每次它进入和离开作用域时进行创建和销毁。

extern存储类

用于提供 一个全局变量的引用,全局变量对所有的程序文件都是可见的。可以这么理解,extern是用来在另一个文件中声明一个全局变量或函数。

指针与引用

什么是指针?

指针是一个 变量,其值为另一个变量的地址。

什么是引用?

引用变量是一个 别名(类似绰号),一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。

指针和引用有何区别?(主要区别)

初始化
引用必须在创建时被初始化;
指针可以在任何时间被初始化;
是否可变
引用只能在定义时被初始化一次(从一而终),之后不可变;
指针可变;
是否可为空
引用不能为空,引用必须连接到一块合法的内存;
指针可以为空。

类和对象

类是什么?

类用于指定对象的形式,它包含了数据表示法用于处理数据的方法。类中的数据和方法称为类的成员。函数在一个类中被称为类的成员。

对象是什么?

对象是根据类来创建的。声明类的对象,就像声明基本类型的变量一样。

类的成员函数是什么?

是指那些把定义和原型写在类定义内部函数,就像类定义中的其他变量一样。

类访问修饰符是什么?

数据封装是面向对象编程的一个重要特点,它防止函数直接访问类的内部成员。类成员的访问限制是通过在类主体内部对各个区域标记 public、private、protected 来指定的,即:访问修饰符。

公有成员public
公有成员在程序中类的外部是可访问的。

私有成员private
私有成员变量或函数在类的外部是不可访问的。只有类和友元函数可以访问私有成员。(默认情况下,类的所有成员都是私有的)

保护成员protected
保护成员变量或函数与私有成员有一点不同:保护成员在派生类中是可访问的。

类构造函数是什么?

类的构造函数是类的一种特殊的成员函数。

使用:它会在每次创建类的新对象时执行。

用途:构造函数可用于为某些成员变量设置初始值

类析构函数是什么?

类的析构函数是类的一种特殊的成员函数。

使用:它会在每次删除所创建的对象时执行。

用途:析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源

友元函数

类的友元函数是定义在类外部,但有权访问类的所有private成员和protected成员;

友元函数并不是成员函数;

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。

内联函数

引入目的:是为了解决程序中函数调用的效率问题,是个空间代价换时间的节省。

原理:程序在编译器编译的时候,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体进行替换,而对于其他的函数,都是在运行时候才被替代

使用:所以内联函数一般都是1-5行的小函数。

this指针

C++中每一个对象都能通过this指针来访问自己的地址。this指针是所有成员函数的隐含参数

使用:在成员函数内部,它可以用来指向调用对象。

注意:友元函数没有this指针,因为友元不是类的成员。只有成员函数才有 this 指针。

static静态成员

使用 static 关键字来把类成员定义为静态的。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本

不会在对象销毁时销毁,所以生命周期较长。

静态成员函数

如果把函数成员声明为静态的,静态成员函数即使在类对象不存在的情况下也能被调用。

静态成员函数只能访问静态成员数据、其他静态成员函数和类外部的其他函数。

静态成员函数与普通成员函数的区别:

静态成员函数没有this指针,只能访问静态成员

普通成员函数有this指针,可以访问类中的任意成员;而静态成员函数没有this指针。

继承

什么是继承?

当创建一个类时,不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类

引入目的是什么?

继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易。这样做也达到了重用代码功能提高执行效率的效果。

访问控制和继承

派生类可以访问基类中所有的非私有成员。因此基类成员如果不想被派生类的成员函数访问,则应在基类中声明为private。

一个派生类继承了所有的基类方法,但下列情况除外:
基类的构造函数、析构函数和拷贝构造函数。
基类的重载运算符。
基类的友元函数。

继承类型有哪几种?

公有继承、保护继承、私有继承

继承中有哪些特点?

三种继承方式相应地改变了基类成员的访问属性。无论哪种继承方式,有两点都没有改变:
1.private成员只能被本类成员(类内)和友元访问,不能被派生类访问;
2.protected成员可以被派生类访问。
具体变化
1.public 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:public, protected, private

2.protected 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:protected, protected, private

3.private 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:private, private, private

重载

重载是什么?

C++ 允许在 同一作用域中的某个函数和运算符 指定多个定义,分别称为函数重载和运算符重载。

重载声明是什么?

重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。

重载决策是什么?

当调用一个重载函数或重载运算符时,编译器通过把你所使用的参数类型与定义中的参数类型进行比较, 决定选用最合适的定义,该过程称为重载决策。

函数重载

同一个作用域内,可以声明几个功能类似的 同名函数,但是这些同名函数的 形式参数(指参数的个数、类型或者顺序)必须不同。不能仅通过返回类型的不同来重载函数。

运算符重载

可以重定义或重载大部分 C++内置的运算符。这样就能使用 自定义类型的运算符。

多态

什么是多态?

当类之间存在层次结构,并且类之间是 通过继承关联时,就会用到多态。C++ 多态意味着调用成员函数时,会对于 不同对象接收相同消息时产生不同的动作

什么时候涉及到多态?

C++的多态性具体体现在 运行和编译两个方面:在 程序运行时的多态性通过 继承和虚函数来体现;在 程序编译时多态性体现在 函数和运算符的重载上;

虚函数是什么?

在基类中冠以关键字virtual的成员函数。 它提供了一种接口界面。
具体解释可以看这个例子,讲的还不错: C++中虚函数的作用是什么?

数据封装

什么是封装?

封装是面向对象编程中的 把数据和操作数据的函数绑定在一起的一个概念。

引入目的是什么?

这样能避免受到外界的 干扰和误用,从而确保了安全。数据封装引申出了 数据隐藏的概念。

实现方法是什么?

C++通过创建 来支持封装和数据隐藏(public、protected、private)。

数据抽象

什么是抽象?

数据抽象是指,只向外界提供关键信息,并隐藏其后台的实现细节。

打个比方?

应用程序可以调用sort() 函数,而不需要知道函数中排序数据所用到的算法。

引入目的是什么?

类的内部受到保护,不会因无意的用户级错误导致对象状态受损;
类实现可能随着时间的推移而发生变化,以便 应对不断变化的需求

实现方法是什么?

抽象把代码分离为 接口和实现。所以在设计组件时,必须 保持接口独立于实现,这样,如果改变底层实现,接口也将保持不变。

数据抽象与数据封装的区别是什么?

数据封装是一种把 数据和操作数据的函数捆绑在一起的机制,数据抽象是一种仅向用户 暴露接口而把具体的实现细节隐藏起来的机制。
简而言之:
封装是函数与数据在一起进行封装。
抽象是仅仅将接口暴露,细节隐藏。

内存管理

为何要进行内存管理?

很多时候,我们 无法提前预知需要多少内存来存储某个定义变量中的特定信息,所需内存的大小 需要在运行时才能确定。

C++程序中的内存空间有哪两个部分?

:在 函数内部声明的所有变量都将占用栈内存。
:这是程序中未使用的内存,在 程序运行时可用于动态分配内存。

C++程序如何进行内存管理?

分配:可以使用 new运算符为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址。
回收:如果您不再需要动态分配的内存空间,可以使用 delete运算符,删除之前由new运算符分配的内存。

new和malloc的区别是什么?

C语言提供了malloc和free函数,完成对堆内存的申请和释放。而C++则提供了两个关键字new和delete;
主要区别
1.使用new操作符申请内存分配时 无须指定内存块的大小,编译器会根据类型信息自行计算;malloc则 需要显式地指出所需内存的尺寸。
2.new和delete是关键字,需要 编译器支持;malloc和free是库函数,需要 头文件支持
3.new操作符内存分配成功时,返回的是 对象类型的指针;而malloc内存分配成功则是返回 void*,因此,malloc的返回值一般都需要进行类型转换。
4.new如果分配失败了就会抛出 bad_malloc的异常,而malloc失败了则会 返回NULL
5.C++ 允许重载new/delete操作符malloc不允许重载

高频面试题汇总

  1. extern的作用是什么?
  2. static的作用是什么?
  3. const的作用是什么?
  4. 指针与引用的区别是什么?
    答:
    ①引用必须被初始化,指针不必。
    ②引用初始化以后不能被改变,指针可以改变所指的对象。
    ③不存在指向空值的引用,但是存在指向空值的指针。
  5. new与malloc的区别是什么?
  6. C++的多态性指什么?
  7. 内联函数,宏定义和普通函数的区别?
  8. 数组指针和指针数组的区别
  9. C++中类与结构体的区别?
  10. 析构函数的作用?
  11. 虚函数的作用?
  12. c语言和c++有什么区别?
  13. 内存溢出,内存泄漏的原因?
  14. 函数参数传递中值传递、地址传递、引用传递有什么区别?
  15. 链表和数组的区别在哪里?
    答:
    数组:数据顺序存储,固定大小;
    链表:数据可以随机存储,大小可动态改变。
  16. C++重写、重载、重定义的区别?
  17. 请说出STL标准模板库中的几个常用类?
  18. 面向对象的三大特征是什么?
  19. 构造函数与析构函数的异同点
  20. 简述C++异常处理方式
  21. 成员函数和友元函数的区别?
  22. 局部变量能否和全局变量重名?
    答:
    能,局部会屏蔽全局。要用全局变量,需要使用"::";
    局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量;
    对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,如:在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。
  23. 全局变量和局部变量在内存中是否有区别?如果有,是什么区别?
    答:
    全局变量储存在静态数据库,局部变量在堆栈
  24. 堆栈溢出一般是由什么原因导致的?
    答:
    没有回收垃圾资源。
  25. 如何引用一个已经定义过的全局变量?
    答:
    可以用引用头文件的方式,也可以用extern关键字
    如果用引用头文件方式来引用某个在头文件中声明的全局变量,假定你将那个变写错了,那么在编译期间会报错;
    如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
  26. Heap与stack的差别?
    答:
    Heap是堆,stack是栈。
    Stack的空间由操作系统自动分配/释放,Heap的空间手动分配/释放;
    Stack空间有限,Heap是很大的自由存储区;
    C中的malloc函数分配的内存空间即在上,C++中对应的是new操作符。
    程序在编译期对变量和函数分配内存都在上进行,且程序运行过程中函数调用时参数的传递也在上进行。
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐