C++ 新特性面试题, C++ 中为什么要引入 make_shared?它有什么优点?
C++ 新特性面试题, C++ 中为什么要引入 make_shared?它有什么优点?
QA
Step 1
Q:: C++
中为什么要引入 make_shared?它有什么优点?
A:: 在 C++11
中,std::make_shared
提供了一种更高效且安全的方式来创建共享指针 (``std::shared_ptr``)
。其优点包括:
1.
效率:make_shared
会在一次内存分配中同时分配对象和控制块(shared_ptr
的引用计数器),避免了分配两次内存,提高了内存分配的效率。
2.
异常安全:使用 new
直接创建对象时,如果在初始化对象后抛出异常,可能会导致内存泄漏。而使用 make_shared
可以确保异常安全,因为内存的分配与初始化是原子操作。
3.
可读性:make_shared
提高了代码的可读性,减少了冗余的 new
关键字,使代码更简洁。
Step 2
Q:: 什么时候使用 shared_ptr 而不是 unique_ptr?
A:: shared_ptr
用于需要多个对象共享同一资源的场景,如引用计数型的资源管理。而 unique_ptr
则用于单一所有权的场景,即某个资源只能有一个所有者,当所有者超出作用域时,资源会自动释放。选择 shared_ptr
还是 unique_ptr
取决于程序的设计需求和资源管理方式。
Step 3
Q:: shared_ptr 和 weak_ptr 有什么区别?
A:: shared_ptr
是一种智能指针,用于共享所有权的对象,每个 shared_ptr
都维护一个引用计数,只有当引用计数为 0
时,资源才会被释放。而 weak_ptr
则是对 shared_ptr
的非所有权引用,不会增加引用计数,主要用于防止 shared_ptr
之间的循环引用问题。weak_ptr
需要通过 lock
方法临时提升为 shared_ptr
才能使用对象。
Step 4
Q:: 如何避免 shared_ptr 循环引用?
A:: 循环引用会导致 shared_ptr
无法正确释放内存。避免循环引用的常用方法是使用 weak_ptr
。weak_ptr
可以引用 shared_ptr
所指向的对象,但不会增加引用计数,从而打破循环引用。
用途
这些面试题主要考察候选人对 C`++ 智能指针机制的理解和实际应用能力。在现代 C++` 编程中,内存管理是一个重要的主题,而智能指针是处理内存管理的常用工具。智能指针的正确使用可以有效防止内存泄漏、悬空指针等问题,因此在生产环境中经常会用到,特别是在涉及到复杂的资源管理或多线程编程时。了解智能指针的使用和它们之间的区别,可以帮助开发者编写更高效、安全的代码。\n相关问题
C++ 进阶面试题, C++ 中为什么要引入 make_shared?它有什么优点?
QA
Step 1
Q:: 为什么要引入 make_shared?
A:: C++ 引入 make_shared 是为了提高内存分配的效率和安全性。make_shared 会在一次内存分配中同时为对象和控制块分配内存,这减少了内存碎片,并且提高了对象的构造和析构的效率。另外,使用 make_shared 可以避免常见的 'new'
运算符的使用错误,例如分配对象后没有正确捕获异常,导致内存泄漏。
Step 2
Q:: make_shared 与 new 的区别是什么?
A:: make_shared 会同时分配对象和引用计数器的内存,而 new 则需要单独分配对象的内存,随后还需要为 std::
shared_ptr 单独分配控制块的内存。这意味着使用 make_shared 可以减少内存分配的次数,提升性能。此外,make_shared 还能避免某些潜在的内存泄漏问题,而直接使用 new 的代码则更容易出错。
Step 3
Q:: 什么时候应该使用 make_shared 而不是 shared_ptr(new ...)
?
A:: 在大多数情况下,优先使用 make_shared,因为它提供了更好的性能和内存使用效率。只有在特定的情况下需要自定义分配器或者需要使用不同的共享指针类型时,才有可能考虑不使用 make_shared。
Step 4
Q:: make_shared 的内部实现机制是怎样的?
A:: make_shared 的实现利用了 C++ 的模板机制,结合了对象和控制块的内存分配。具体来说,它通过 std::
allocate_shared 分配了一块连续的内存区域,这块区域既包含了对象本身,也包含了用于引用计数的控制块。通过这种方式,make_shared 不仅减少了内存碎片,还提升了内存的局部性。