1.C++在main函数执行前与执行之后会进行什么操作?¶
main
函数执行前:¶
- 全局对象的构造:编译器会先构造全局对象和静态存储期的对象。这些对象的构造顺序是根据它们定义的顺序,而不是它们声明的顺序。
- 初始化静态成员变量:对于类的静态成员变量,编译器会进行初始化(存疑,c++应该是第一次使用时分配内存并初始化)。
- 调用构造函数:对于全局和静态对象,编译器会调用它们的构造函数。
- 执行全局初始化代码:任何在函数外部定义的全局初始化代码会被执行。
main
函数执行后:¶
main
函数返回:main
函数执行完毕后,会返回一个值给操作系统。- 局部对象的析构:
main
函数中的局部对象会被销毁,它们的析构函数会被调用。 - 全局对象的析构:全局对象和静态存储期的对象的析构函数会被调用,顺序是构造函数调用的逆序。
- 程序终止:程序执行完毕后,操作系统会接管控制权,结束程序的运行。
- 资源回收:操作系统会回收程序所占用的资源,如内存等。
2.讲一下指针与引用,他们在传参的时候有什么异同?¶
- 指针存储地址,可以修改
- 引用是变量的别名,无空间不会增加新的内存,不能修改,必须初始化.
3. 构造函数可不可以是虚函数¶
- 初始化阶段:当一个对象被创建时,构造函数会被调用以初始化该对象。在对象的构造过程中,虚函数表(vtable)还没有被完全设置好,因此无法使用虚函数机制。
- 对象类型已知:在调用构造函数时,对象的类型是已知的,编译器可以确定调用哪个构造函数。而虚函数的调用是在运行时根据对象的实际类型来决定的,这与构造函数的调用时机和方式不符。
- 对象状态未完全建立:在构造函数执行的过程中,对象的状态可能还没有完全建立,这意味着在构造函数中调用虚函数可能会导致未定义行为,因为虚函数可能依赖于对象的完整状态。
- 资源分配:构造函数通常用于分配资源和初始化成员变量,这些操作通常需要在对象的生命周期开始时就完成,而不是推迟到运行时。
- 多态性的目的:多态性是为了在运行时根据对象的实际类型来调用相应的函数,而构造函数的调用是在编译时就已经确定的,因此不需要多态性。
4.Nullptr与NULL的区别?¶
-
- 类型和定义:
NULL
是一个宏定义,通常被定义为0
或(void*)0
,它的类型是int
或void*
。nullptr
是C++11引入的字面量,其类型是std::nullptr_t
,是一个真正的指针类型。
- 类型安全:
NULL
由于是int
或void*
类型,所以它不是类型安全的。在某些情况下,你可能会不小心将NULL
与整型值混淆。NULL
在表达式中会被替换为0
或(void*)0
,这可能会导致一些隐式类型转换。nullptr
是类型安全的,它只能被用作指针,不能被误用为整型值。nullptr
在表达式中保持其指针类型,不会进行隐式类型转换,这使得代码更加清晰和安全。
-
nullptr的优势:
nullptr
可以用于任何指针类型,包括成员指针和空值指针,而NULL
则不能。nullptr
与NULL
相比,提供了更好的重载决议,因为它可以区分不同的指针类型。
6.移动端怎么处理多光源问题¶
- 延迟渲染(Deferred Rendering):减少灯光渲染次数
- Cluster-Based Lighting:它通过将视锥体划分为多个Cluster,并为每个Cluster计算影响它的光源列表,从而减少Pixel Shader的计算量。
- Tiled-Based Rendering:- 基于Tile的渲染技术可以将屏幕划分为多个小区域(Tile),然后对每个Tile单独进行光照计算。这种方法可以减少不必要的计算,提高效率。
- 多光源数据组织:
- 当场景中的光源特别多时,可以使用BVH(Bounding Volume Hierarchy)来组织光源,提高光源剔除的效率。
- Tiled Point Light:算每个tile贡献最大的几个点光源,减少每个顶点/像素需要计算的光源数量,从而降低开销。