跳转至

1.C++在main函数执行前与执行之后会进行什么操作?

main函数执行前:

  1. 全局对象的构造:编译器会先构造全局对象和静态存储期的对象。这些对象的构造顺序是根据它们定义的顺序,而不是它们声明的顺序。
  2. 初始化静态成员变量:对于类的静态成员变量,编译器会进行初始化(存疑,c++应该是第一次使用时分配内存并初始化)。
  3. 调用构造函数:对于全局和静态对象,编译器会调用它们的构造函数。
  4. 执行全局初始化代码:任何在函数外部定义的全局初始化代码会被执行。

main函数执行后:

  1. main函数返回main函数执行完毕后,会返回一个值给操作系统。
  2. 局部对象的析构main函数中的局部对象会被销毁,它们的析构函数会被调用。
  3. 全局对象的析构:全局对象和静态存储期的对象的析构函数会被调用,顺序是构造函数调用的逆序。
  4. 程序终止:程序执行完毕后,操作系统会接管控制权,结束程序的运行。
  5. 资源回收:操作系统会回收程序所占用的资源,如内存等。

2.讲一下指针与引用,他们在传参的时候有什么异同?

  • 指针存储地址,可以修改
  • 引用是变量的别名,无空间不会增加新的内存,不能修改,必须初始化.

3. 构造函数可不可以是虚函数

  1. 初始化阶段:当一个对象被创建时,构造函数会被调用以初始化该对象。在对象的构造过程中,虚函数表(vtable)还没有被完全设置好,因此无法使用虚函数机制。
  2. 对象类型已知:在调用构造函数时,对象的类型是已知的,编译器可以确定调用哪个构造函数。而虚函数的调用是在运行时根据对象的实际类型来决定的,这与构造函数的调用时机和方式不符。
  3. 对象状态未完全建立:在构造函数执行的过程中,对象的状态可能还没有完全建立,这意味着在构造函数中调用虚函数可能会导致未定义行为,因为虚函数可能依赖于对象的完整状态。
  4. 资源分配:构造函数通常用于分配资源和初始化成员变量,这些操作通常需要在对象的生命周期开始时就完成,而不是推迟到运行时。
  5. 多态性的目的:多态性是为了在运行时根据对象的实际类型来调用相应的函数,而构造函数的调用是在编译时就已经确定的,因此不需要多态性。

4.Nullptr与NULL的区别?

    1. 类型和定义
    2. NULL是一个宏定义,通常被定义为0(void*)0,它的类型是intvoid*
    3. nullptr是C++11引入的字面量,其类型是std::nullptr_t,是一个真正的指针类型。
  • 类型安全
    • NULL由于是intvoid*类型,所以它不是类型安全的。在某些情况下,你可能会不小心将NULL与整型值混淆。
    • NULL在表达式中会被替换为0(void*)0,这可能会导致一些隐式类型转换。
    • nullptr是类型安全的,它只能被用作指针,不能被误用为整型值。
    • nullptr在表达式中保持其指针类型,不会进行隐式类型转换,这使得代码更加清晰和安全。
  • nullptr的优势

    • nullptr可以用于任何指针类型,包括成员指针和空值指针,而NULL则不能。
    • nullptrNULL相比,提供了更好的重载决议,因为它可以区分不同的指针类型。

6.移动端怎么处理多光源问题

  • 延迟渲染(Deferred Rendering):减少灯光渲染次数
  • Cluster-Based Lighting:它通过将视锥体划分为多个Cluster,并为每个Cluster计算影响它的光源列表,从而减少Pixel Shader的计算量。
  • Tiled-Based Rendering:- 基于Tile的渲染技术可以将屏幕划分为多个小区域(Tile),然后对每个Tile单独进行光照计算。这种方法可以减少不必要的计算,提高效率。
  • 多光源数据组织
    • 当场景中的光源特别多时,可以使用BVH(Bounding Volume Hierarchy)来组织光源,提高光源剔除的效率。
  • Tiled Point Light:算每个tile贡献最大的几个点光源,减少每个顶点/像素需要计算的光源数量,从而降低开销。