十万字吐血整理的C/C++、嵌入式常见面试题!!!!

欢迎订阅,希望能点个赞!!!!

正在持续更新!!!!!欢迎探讨!!!

完整专栏地址:https://blog.nowcoder.net/zhuanlan/gmPWX0


相关知识点都能零星在网上找到,这个文章系列将目前遇到的所有常见面试问题进行一个汇总。

文中很多资料避免不了从网上或是其他复习资料里收集整理,十分感谢前辈的辛勤付出,如果存在侵权请一定联系我进行删除

也有相当一部分是本人在经历提前批以及秋招的过程中遇到和验证过的。


系列文章PDF下载地址:《最全C_C++及嵌入式软开面试题宝典.pdf》




38、 构造函数的执行顺序?析构函数的执行顺序?构造函数内部干了啥?拷贝构造干了啥?

1、构造函数顺序

1.基类构造函数。如果有多个基类,则构造函数的调用顺序是某类在类派生表中出现的顺序,而不是它们在成员初始化表中的顺序。

2.成员类对象构造函数。如果有多个成员类对象则构造函数的调用顺序是对象在类中被声明的顺序,而不是它们出现在成员初始化表中的顺序。

3.派生类构造函数。

2、析构函数顺序

1.调用派生类的析构函数;

2.调用成员类对象的析构函数;

3.调用基类的析构函数。

39、虚析构函数的作用,父类的析构函数是否要设置为虚函数?

1.C++中基类采用virtual虚析构函数是为了防止内存泄漏。具体地说,如果派生类中申请了内存空间,并在其析构函数中对这些内存空间进行释放。假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数。那么在这种情况下,派生类中申请的空间就得不到释放从而产生内存泄漏。所以,为了防止这种情况的发生,C++中基类的析构函数应采用virtual虚析构函数。

2.纯虚析构函数一定得定义,因为每一个派生类析构函数会被编译器加以扩张,以静态调用的方式调用其每一个虚基类以及上一层基类的析构函数。因此,缺乏任何一个基类析构函数的定义,就会导致链接失败。因此,最好不要把虚析构函数定义为纯虚析构函数。

40、构造函数析构函数可否抛出异常

1.C++只会析构已经完成的对象,对象只有在其构造函数执行完毕才算是完全构造妥当。在构造函数中发生异常,控制权转出构造函数之外。因此,在对象b的构造函数中发生异常,对象b的析构函数不会被调用。因此会造成内存泄漏。

2.用auto_ptr对象来取代指针类成员,便对构造函数做了强化,免除了抛出异常时发生资源泄漏的危机,不再需要在析构函数中手动释放资源;

3.如果控制权基于异常的因素离开析构函数,而此时正有另一个异常处于作用状态,C++会调用terminate函数让程序结束;

4.如果异常从析构函数抛出,而且没有在当地进行捕捉,那个析构函数便是执行不全的。如果析构函数执行不全,就是没有完成他应该执行的每一件事情。

41、类如何实现只能静态分配和只能动态分配

1.前者是把new、delete运算符重载为private属性;后者是把构造、析构函数设为protected属性,再用子类来动态创建;

2.建立类的对象有两种方式:

eq \o\ac(,1)1静态建立,静态建立一个类对象,就是由编译器为对象在栈空间中分配内存;

eq \o\ac(,2)2动态建立,A *p = new A();动态建立一个类对象,就是使用new运算符为对象在堆空间中分配内存。这个过程分为两步,第一步执行operator new()函数,在堆中搜索一块内存并进行分配;第二步调用类构造函数构造对象;

3.只有使用new运算符,对象才会被建立在堆上,因此只要限制new运算符就可以实现类对象只能建立在栈上。可以将new运算符设为私有。

42、如果想将某个类用作基类,为什么该类必须定义而非声明?

派生类中包含并且可以使用它从基类继承而来的成员,为了使用这些成员,派生类必须知道他们是什么。

43、什么情况会自动生成默认构造函数?

1.带有默认构造函数的类成员对象,如果一个类没有任何构造函数,但它含有一个成员对象(另一个类的对象是这个类的成员),而后者有默认构造函数,那么编译器就为该类合成出一个默认构造函数。不过这个合成操作只有在构造函数真正被需要的时候才会发生;如果一个类A含有多个成员类对象的话,那么类A的每一个构造函数必须调用每一个成员对象的默认构造函数而且必须按照类对象在类A中的声明顺序进行;

2.带有默认构造函数的基类,如果一个没有任何构造函数的派生类派生自一个带有默认构造函数基类,那么该派生类会合成一个构造函数调用上一层基类的默认构造函数;

3.带有一个虚函数的类

4.带有一个虚基类的类

5.合成的默认构造函数中,只有基类子对象和成员类对象会被初始化。所有其他的非静态数据成员都不会被初始化。

44、构造函数的扩展过程?

1.记录在成员初始化列表中的数据成员初始化操作会被放在构造函数的函数体内,并与成员的声明顺序为顺序;

2.如果一个成员并没有出现在成员初始化列表中,但它有一个默认构造函数,那么默认构造函数必须被调用;

3.如果class有虚表,那么它必须被设定初值;

4.所有上一层的基类构造函数必须被调用;

5.所有虚基类的构造函数必须被调用。

45、 程序员定义的析构函数被扩展的过程?

1.析构函数函数体被执行;

2.如果class拥有成员类对象,而后者拥有析构函数,那么它们会以其声明顺序的相反顺序被调用;

3.如果对象有一个vptr,现在被重新定义

4.如果有任何直接的上一层非虚基类拥有析构函数,则它们会以声明顺序被调用;

5.如果任何虚基类拥有析构函数