C++面试题

1.什么是多态?多态怎么实现的?

父类指针指向一个子类对象,然后通过父亲的指针调用子类的成员函数

多态:不同对象接收相同的消息产生不同的动作。多态包括 编译时多态和 运行时多态

    运行时多态是:通过继承和虚函数来体现的。
       编译时多态:运算符重载上。

下面是构成多态的条件:(缺一不可!!!!!)

    • 必须存在继承关系;
    • 继承关系中必须有同名的虚函数,并且它们是遮蔽(覆盖)关系。
    • 存在父类的指针,通过该指针调用虚函数(通过父类指针操作子类对象)

虚函数实现多态的原理?

多态是基于虚函数的,虚函数是通过一张虚函数表(Virtual Table)来实现的

每个虚函数列表都有一根装着虚函数列表地址的指针vfptr,vfptr去记录这个类所使用的虚函数列表,虚函数列表的每个元素都是一个函数指针,指向一个虚函数或者子类重写的函数(子类重写后就会覆盖原来父类的),子类先将父类的虚函数列表拷贝过来,通过父类指针去调用虚函数,通过vfptr去找到虚函数列表中的函数看子类里面有没有重写虚函数的,如果有,则覆盖该函数。

虚函数, 纯虚函数:

虚函数: 在基类中用virtual的成员函数。允许在派生类中对基类的虚函数重新定义。
       基类的虚函数可以有函数体,基类也可以实例化。
       虚函数要有函数体,否则编译过不去。
       虚函数在子类中可以不覆盖。
       构造函数不能是虚函数。

纯虚函数:基类中为其派生类保留一个名字,以便派生类根据需要进行定义。
       包含一个纯虚函数的类是抽象类。
       纯虚函数后面有 = 0;
       抽象类不可以实例化。但可以定义指针。
       如果派生类如果不是先基类的纯虚函数,则仍然是抽象类。
       抽象类可以包含虚函数。

2.对类怎么看的?

3.new/delete 与 malloc/free的区别?

1.new/delete是c++运算符,malloc/free是c的库函数

2.new 在申请内存的同时,还会调用对象的构造函数,而 malloc 只会申请内存;同样,delete 在释放内存之前,会调用对象的析构函数,而 free 只会释放内存。

3.new/delete的底层调用了malloc/free。

4.new的安全性要高一些,因为他返回的就是一个所创建的对象的指针,对于malloc来说返回的则是void*,需要手动计算类型大小,进行强制类型转换,显然这是一个危险的漏洞。

4.什么是抽象类?抽象类和接口有什么区别?

抽象类是特殊的类,只是不能被实例化含有纯虚函数的类被称为抽象类),除此以外,具有类的其他特性.

接口:接口是一个概念。它在C++中用抽象类来实现.

一个类一次可以实现若干个接口,但是只能扩展一个(抽象类)父类  ;

抽象类在定义类型方法的时候,可以给出方法的实现部分,也可以不给出;而对于接口来说,其中所定义的方法都不能给出实现部分。

抽象类可以既包含数据成员又包含方法。  

接口中不可以用虚方法,也不可以包含已经实现的方法

5.你对C++11了解么?

C++11标准为C++编程语言的第三个官方标准,C++11引入了多线程和原子操作的类库,新标准nullptr,从此以后,C++语言本身有了并发编程的能力,一个 thread类,三五行代码,就可以启动一个线程,简单的使用mutex和lock_guard ,就可以完成线程间的资源同步与保护,it is cool。

6.什么是“引用”?声明和使用“引用”要注意哪些问题?

引用是C++语言的一个特殊的数据类型描述,用于在程序的不同的部分使用两个以上的变量名指向同一块地址,使得对其中任何一个变量的操作实际上都是对同一地址单元进行的。

引用的特点:

1.一个变量可取多个别名。

2.引用必须初始化。

3.引用只能在初始化的时候引用一次 ,不能更改为转而引用其他变量。

4.对引用进行操作,实际上就是对被引用的变量进行操作,

5.引用仅是变量的别名,而不是实实在在地定义了一个变量,因此引用本身并不占用内存,而是和目标变量共同指向目标变量的内存地址.声明引用时,目标的存储状态不会改变

6.表达式中的取地址符&不再是取变量的地址,而是用来表示该变量是引用类型的变量。

7.引用和指针的区别和联系(笔试热点)

1.指针的作用有:(1).装地址(2).不同变量访问同一块空间

 引用:只可以实现用不同变量访问同一块空间

 2.引用定义了就一定要初始化,指针不用

 3.引用初始化后就不能再引用其他空间了

 4. 没有空的引用,指针可以为空(引用一定要保证引用的时一个合法的存储单元)(在c++中NULL就是0,而c中的NULL是空地址(void*)0)

 5. “sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;

 6. 指针和引用的自增(++)运算意义不一样;引用是值的增减,指针是地址的偏移

 7.从内存分配上看:程序为指针变量分配内存区域,而引用不需要分配内存区域。

8. 将引用作为函数参数有哪些特点   

(1)与指针调用效果一样。 
(2)引用传参,内存中并没有产生副本。
(3)用指针传递,也要给形参分配存储单元;并且需要使用"*变量的"的形式,可读性差;另外,调用的地方还得用地址作为实参。

9.什么时候用常引用

用这种方式声明的引用,不能通过引用对目标变量的值进行修改,从而使引用的目标成为const,达到了引用的安全性。

10 .重载和重写

 main函数之前会执行什么代码?

全局变量的初始化。

 数组和指针的区别

数组名不能自加自减,但是指针可以。

 为什么基类的析构函数是虚函数?

 动态绑定,不会造成潜在的内存泄漏

const与static的用法

const:
    修饰类成员变量,成员不可以改。

               修饰函数参数;

               修饰返回值;
    修饰函数,函数不会修改类内的数据成员。不会调用非const成员函数。(在函数末尾,默认是const this指针,不能修改成员)
    const函数只能调用const函数,非const函数可以调用const函数。
  static:
    局部static变量:局部静态变量,处于内存中的静态存储区;只能初始化一次;作用域是局部。
    全局static变量:全局静态变量,静态存储区;全局静态变量的作用局是声明它的文件,在文件之外是不可见的。其实是从
    定义的地方到文件结尾。

  类的static成员:类的全局变量,被类的所有独享共享,包括派生类的对象。按照这种方式int base::var = 10;进行
  初始化,不能在构造函数内初始化,但是可以用const修饰的static数据成员在类内初始化。

  static修饰成员函数,类只有一份,不含this指针。
  static成员变量定义放在cpp文件中。 const static 可以就地初始化。

类的static变量在什么时候初始化,函数的static变量什么时候初始化?

  类的静态成员在类实例化之前就存在了; 函数的static变量在执行此函数时进行实例化(第一次调用的时候,只初始化一次)

栈溢出几种情况

一、局部数组过大。当函数内部的数组过大时,有可能导致堆栈溢出。

二、递归调用层次太多。递归函数在运行时会执行压栈操作,当压栈次数太多时,也会导致堆栈溢出。

三、指针或数组越界。这种情况最常见,例如进行字符串拷贝,或处理用户输入等等。

原文地址:https://www.cnblogs.com/curo0119/p/8560661.html