编程语言C++
类的大小
|
|
C/C++内存对齐
C++空类占用一字节
结构体大小
注意:
|
|
A的大小是3,结构体中每个成员的起始地址是min(成员类型大小,pack)
的整数倍,整个结构体大小是最大成员大小的整数倍。
C++虚函数作用及底层实现原理
C++中虚继承的作用及底层实现原理
- 虚继承用于解决多继承条件下的菱形继承问题,底层实现原理与编译器相关,一般通过虚基类指针实现,即各对象中只保存一份父类的对象,多继承时通过虚基类指针引用该公共对象,从而避免菱形继承中的二义性问题。
- C++ 多继承和虚继承的内存布局
Struct和Class的区别
C++中包含哪几种强制类型转换?他们有什么区别和联系?
请简述智能指针原理,并实现一个简单的智能指针
|
|
Part2
内联函数、构造函数、静态成员函数可以是虚函数吗?
- 都不可以。内联函数需要在编译阶段展开,而虚函数是运行时动态绑定的,编译时无法展开; 构造函数在进行调用时还不存在父类和子类的概念,父类只会调用父类的构造函数,子类调用子类的,因此不存在动态绑定的概念;静态成员函数是以类为单位的函数,与具体对象无关,虚函数是与对象动态绑定的,因此是两个不冲突的概念;
构造函数中可以调用虚函数吗?
- 可以,但是没有动态绑定的效果,父类构造函数中调用的仍然是父类版本的函数,子类中调用的仍然是子类版本的函数
- 样例错题5
虚函数不能是内联函数
- 虚函数不能是内联函数(编译时展开,必须有实体),不能是静态函数(属于自身类,不属于对象,而虚函数要求有实体),不能是构造函数(尚未建立虚函数表)。
C++中成员函数能够同时用static和const进行修饰?
- 否,因为static表⽰示该函数为静态成员函数,为类所有;而const是用于修饰成员函数的,两者相矛盾。
[Error] static member function 'static void Test::fun()' cannot have cv-qualifier
C++ 内联函数
C/C++参数传递顺序
volatile有什么作用?
- volatile定义变量的值是易变的,每次用到这个变量的值的时候都要去重新读取这个变量的值,而不是读寄存器内的备份。
- 多线程中被几个任务共享的变量需要定义为volatile类型。
delete和delete[]区别?
- delete只会调用一次析构函数。
- delete[]会调用数组中每个元素的析构函数。
面向对象三大特性?
- 封装性:数据和代码捆绑在一起,避免外界干扰和不确定性访问。
- 继承性:让某种类型对象获得另一个类型对象的属性和方法。
- 多态性:同一事物表现出不同事物的能力,即向不同对象发送同一消息,不同的对象在接收时会产生不同的行为(重载实现编译时多态,虚函数实现运行时多态)。
构造函数能否为虚函数,析构函数呢?
- 析构函数:
- 析构函数可以为虚函数,并且一般情况下基类析构函数要定义为虚函数。
- 只有在基类析构函数定义为虚函数时,调用操作符delete销毁指向对象的基类指针时,才能准确调用派生类的析构函数(从该级向上按序调用虚函数),才能准确销毁数据。
- 析构函数可以是纯虚函数,含有纯虚函数的类是抽象类,此时不能被实例化。但派生类中可以根据自身需求重新改写基类中的纯虚函数。
- 构造函数:
- 构造函数不能定义为虚函数,不仅如此,构造函数中还不能调用虚函数。因为那样实际执行的是父类对应的函数,因为自己还没有构造好(构造顺序先基类再派生类)。
C语言0长度数组(可变数组/柔性数组)
有哪几种情况只能用intialization list而不能用assignment?
- 当类中含有const成员变量;基类无默认构造函数时,有参的构造函数都需要初始化表;当类中含有reference成员变量。
关于const int* 和int const *及int * const
Part3
static作用是什么?在C和C++中有何区别?
- static可以修饰局部变量(静态局部变量)、全局变量(静态全局变量)和函数,被修饰的变量存储位置在静态区。对于静态局部变量,相对于一般局部变量其生命周期长,直到程序运行结束而非函数调用结束,且只在第一次被调用时定义;对于静态全局变量,相对于全局变量其可见范围被缩小,只能在本文件中可见;修饰函数时作用和修饰全局变量相同,都是为了限定访问域。
- C++的static除了上述两种用途,还可以修饰类成员(静态成员变量和静态成员函数),静态成员变量和静态成员函数不属于任何一个对象,是所有类实例所共有。
- static的数据记忆性可以满足函数在不同调用期的通信,也可以满足同一个类的多个实例间的通信。
- 未初始化时,static变量默认值为0。
malloc和new的区别?
- malloc和free是标准库函数,支持覆盖;new和delete是运算符,并且支持重载。
- malloc仅仅分配内存空间,free仅仅回收空间,不具备调用构造函数和析构函数功能,用malloc分配空间存储类的对象存在风险;new和delete除了分配回收功能外,还会调用构造函数和析构函数。
- malloc和free返回的是void类型指针(必须进行类型转换),new和delete返回的是具体类型指针。
指针和引用区别?
- 引用只是别名,不占用具体存储空间,只有声明没有定义;指针是具体变量,需要占用存储空间。
- 引用在声明时必须初始化为另一变量,一旦出现必须为typename refname &varname形式;指针声明和定义可以分开,可以先只声明指针变量而不初始化,等用到时再指向具体变量。
- 引用一旦初始化之后就不可以再改变(变量可以被引用为多次,但引用只能作为一个变量引用);指针变量可以重新指向别的变量。
- 不存在指向空值的引用,必须有具体实体;但是存在指向空值的指针。
构造函数调用顺序,析构函数呢?
- 基类的构造函数:如果有多个基类,先调用纵向上最上层基类构造函数,如果横向继承了多个类,调用顺序为派生表从左到右顺序。
- 成员类对象的构造函数:如果类的变量中包含其他类(类的组合),需要在调用本类构造函数前先调用成员类对象的构造函数,调用顺序遵照在类中被声明的顺序。
- 派生类的构造函数。
- 析构函数与之相反。
虚函数和纯虚函数区别?
- 虚函数是为了实现动态编联产生的,目的是通过基类类型的指针指向不同对象时,自动调用相应的、和基类同名的函数(使用同一种调用形式,既能调用派生类又能调用基类的同名函数)。虚函数需要在基类中加上virtual修饰符修饰,因为virtual会被隐式继承,所以子类中相同函数都是虚函数。当一个成员函数被声明为虚函数之后,其派生类中同名函数自动成为虚函数,在派生类中重新定义此函数时要求函数名、返回值类型、参数个数和类型全部与基类函数相同。
- 纯虚函数只是相当于一个接口名,但含有纯虚函数的类不能够实例化。
覆盖、重载和隐藏的区别?
- 覆盖是派生类中重新定义的函数,其函数名、参数列表(个数、类型和顺序)、返回值类型和父类完全相同,只有函数体有区别。派生类虽然继承了基类的同名函数,但用派生类对象调用该函数时会根据对象类型调用相应的函数。覆盖只能发生在类的成员函数中。
- 隐藏是指派生类函数屏蔽了与其同名的函数,这里仅要求基类和派生类函数同名即可。其他状态同覆盖。可以说隐藏比覆盖涵盖的范围更宽泛,毕竟参数不加限定。
- 重载是具有相同函数名但参数列表不同(个数、类型或顺序)的两个函数(不关心返回值),当调用函数时根据传递的参数列表来确定具体调用哪个函数。重载可以是同一个类的成员函数也可以是类外函数。
在main执行之前执行的代码可能是什么?
- 全局对象的构造函数。
构造函数和析构函数调用时机?
- 全局范围中的对象:构造函数在所有函数调用之前执行,在主函数执行完调用析构函数。
- 局部自动对象:建立对象时调用构造函数,函数结束时调用析构函数。
- 动态分配的对象:建立对象时调用构造函数,调用释放时调用析构函数。
- 静态局部变量对象:建立时调用一次构造函数,主函数结束时调用析构函数。
错题1
|
|
错题2
|
|
错题3
|
|
错题4
|
|
错题5
|
|