FHangH / AuroraBlogTalk

0 stars 0 forks source link

C++面试总结 #35

Open FHangH opened 4 months ago

FHangH commented 4 months ago

https://fangh.space/post/1_09_C++%E9%9D%A2%E8%AF%95%E6%80%BB%E7%BB%93?code=9403ad1a0efbe9504f6a#36-%E4%B8%8D%E5%85%81%E8%AE%B8%E9%87%8D%E8%BD%BD%E7%9A%84%E8%BF%90%E7%AE%97%E7%AC%A6 C++面试1. 线程和进程的区别 线程和进程是操作系统中的两个基本概念。 线程是进程的一部分,它是操作系统调度的基本单位,而进程是一个具有一定独立功能的程序关于...

FHangH commented 3 months ago

C++11 特性修改 const相关内容:

auto i; 这是一个类型推断声明,i 的类型将由编译器根据初始化时的右值来推断。例如,如果你写 auto i = 42;,i 的类型将被推断为 int。如果 i 没有被初始值赋值,则这是一个错误,因为 auto 需要一个初始值来推断类型。

const auto i; 这与第一种声明类似,但 i 被声明为常量。i 不能被赋予不同的值,其类型将由初始赋值确定。同样,它必须在声明时初始化,否则会导致编译错误,例如:const auto i = 42;。

auto &i; 这是一个引用声明,i 将成为另一个变量的引用,其类型由右值推断出来。要注意,引用必须在声明时初始化,并且引用的变量不可以是临时值,例如:int x = 42; auto &i = x;。这样,i 将是 x 的别名,与 x 共享相同的值和存储空间。

const auto &i; 这是一个常量引用声明,i 将是一个不可变的引用,引用的对象不能通过 i 被修改。常量引用在声明时同样需要初始化,并且是个好的实践,当你想要防止修改被引用的对象,或者避免不必要的拷贝而使用。例如:const auto &i = x;。这对于传递大型对象到函数中时很有帮助,不仅可以避免拷贝还保持了对象的常量性。

FHangH commented 3 months ago

C++ 大端,小端补充:

在C++中,判断CPU是否使用大端(Big-Endian)或小端(Little-Endian)的数据存储方式,可以通过检查一个具体的数值的内存表示来实现。其中一个常用的方法是使用联合(union)来让同一段内存以不同的数据类型来解读,并检查哪个字节包含数值的最低位。

以下是一个C++示例函数,用于检测当前系统是大端还是小端:

include

bool IsLittleEndian() { union { uint32_t i; char c[4]; } testUnion = {0x01020304};

// 在小端系统中,最低字节(0x04)将是首字节
return testUnion.c[0] == 0x04;

}

int main() { if (IsLittleEndian()) { std::cout << "系统是小端模式 (Little-Endian)." << std::endl; } else { std::cout << "系统是大端模式 (Big-Endian)." << std::endl; }

return 0;

} 上述代码定义了一个联合testUnion,它包含一个uint32_t类型的整数和一个长度为4的char数组。当用数值0x01020304初始化这个联合的uint32_t成员时,char数组的顺序将取决于是大端还是小端:

在小端系统中,最低有效字节(这里是0x04)将存储在地址最低的单元(char数组的第一个元素)。 在大端系统中,最高有效字节(这里是0x01)将存储在地址最低的单元。 因此,通过比较testUnion.c[0]是否等于0x04,函数IsLittleEndian能够判断出当前系统的端序。

请注意,使用联合来进行类型混淆可能不是所有环境都支持的行为,并且在某些编译器设置或语言标准下可能被视为未定义行为(Undefined Behavior)。一个更加可移植的(但可能效率稍低的)方法是使用指针操作:

bool IsLittleEndian() { uint32_t num = 1; return reinterpret_cast<char>(&num) == 1; } 在这里,我们创建了一个uint32_t的变量num,并将数值1赋给它。然后,我们使用reinterpret_cast将整数的地址转换为char*指针,并检查首个字节是否为1。如果是,则说明最低有效字节存储在最低地址,因此系统为小端模式。

FHangH commented 3 months ago

在Unreal Engine(UE)中,资源管理是游戏开发过程中的一个关键部分。对资源的引用主要分为两种:硬引用(Hard References)和软引用(Soft References)。这两种引用类型的区别对于理解引擎的加载和内存管理机制至关重要。

硬引用(Hard References)

硬引用是对资源的直接、强制性链接。当一个资源被硬引用时,该资源会成为包(Package)加载进内存的一部分。这意味着:

示例:在一个Actor的蓝图中直接放置一个静态网格体组件(Static Mesh Component)并为其指定一个模型(Static Mesh),这将创建一个硬引用。当这个Actor蓝图被加载时,相关的静态网格体资源也会被加载。

UStaticMesh* MyStaticMesh; // 这是一个硬引用,静态网格体资源会随着加载这个类而加载到内存中

软引用(Soft References)

软引用,又称为动态引用,是一种非强制性的链接。软引用允许在不直接加载资源的情况下引用它。这意味着:

示例:在游戏中,你可能需要“按需”加载某个关卡的内容。在这种情况下,你可以使用软引用来存储关卡的引用,并在玩家接近该地区时动态加载关卡资源。这允许你控制资源的加载时机,从而进行优化内存使用和提高加载效率。

// C++中软引用的声明
// 声明一个软引用,它不会自动加载
TSoftObjectPtr<UStaticMesh> SoftMeshReference;

// C++中加载软引用的资源
// 显式加载软引用对应的静态网格体资源
UStaticMesh* ActualMesh = SoftMeshReference.LoadSynchronous();

在UE编辑器中,你可以通过资产管理器(Asset Manager)配置资源的引用类型,控制哪些资源应始终加载,哪些资源可以动态加载。

总结一下,硬引用确保了资源的可用性,但可能会带来不必要的性能开销。软引用提供了灵活的资源管理,使得可以实现更加高效的资源加载策略。正确地使用这两种引用类型,对于优化游戏性能和资源管理非常关键。