面试题答案
一键面试智能指针工作原理
std::unique_ptr
:- 原理:
std::unique_ptr
是一种独占式智能指针,它拥有对对象的唯一所有权。当std::unique_ptr
被销毁时,它所指向的对象也会被自动销毁。这通过移动语义来实现,std::unique_ptr
不支持拷贝构造函数和拷贝赋值运算符,但支持移动构造函数和移动赋值运算符。 - 示例:
- 原理:
std::unique_ptr<int> ptr1 = std::make_unique<int>(42);
std::unique_ptr<int> ptr2 = std::move(ptr1); // ptr1 现在为空,ptr2 拥有对象
std::shared_ptr
:- 原理:
std::shared_ptr
是一种共享式智能指针,多个std::shared_ptr
可以指向同一个对象。它使用引用计数来管理对象的生命周期,每当有一个新的std::shared_ptr
指向该对象时,引用计数加 1;当一个std::shared_ptr
被销毁或指向其他对象时,引用计数减 1。当引用计数为 0 时,对象被自动销毁。 - 示例:
- 原理:
std::shared_ptr<int> ptr1 = std::make_shared<int>(42);
std::shared_ptr<int> ptr2 = ptr1; // 引用计数增加
内存管理优势
- 自动内存释放:智能指针在其作用域结束时,会自动释放所指向的内存,避免了手动调用
delete
可能导致的内存泄漏问题。 - 异常安全:在存在异常的情况下,智能指针能确保在异常抛出时,其所管理的内存依然能被正确释放,保证程序的健壮性。
复杂数据结构(树形结构)中智能指针的使用
- 使用
std::unique_ptr
构建树形结构:- 优点:如果树节点之间是父子关系,每个节点应该唯一拥有其孩子节点,使用
std::unique_ptr
可以清晰地表达这种所有权关系,并且在节点被删除时,其孩子节点也会被自动删除。 - 示例:
- 优点:如果树节点之间是父子关系,每个节点应该唯一拥有其孩子节点,使用
struct TreeNode {
int value;
std::unique_ptr<TreeNode> left;
std::unique_ptr<TreeNode> right;
TreeNode(int val) : value(val) {}
};
- 使用
std::shared_ptr
构建树形结构:- 优点:当树结构中有共享节点的情况,例如某些子树可能被多个父节点共享时,
std::shared_ptr
可以确保共享节点在所有引用都消失时才被删除。 - 示例:
- 优点:当树结构中有共享节点的情况,例如某些子树可能被多个父节点共享时,
struct TreeNode {
int value;
std::shared_ptr<TreeNode> left;
std::shared_ptr<TreeNode> right;
TreeNode(int val) : value(val) {}
};
- 避免循环引用:在树形结构中使用
std::shared_ptr
时,要特别注意避免循环引用,因为循环引用会导致引用计数永远不会为 0,从而造成内存泄漏。可以使用std::weak_ptr
来打破循环引用。- 示例:
struct TreeNode {
int value;
std::shared_ptr<TreeNode> parent;
std::weak_ptr<TreeNode> child;
TreeNode(int val) : value(val) {}
};
通过合理使用 std::unique_ptr
、std::shared_ptr
和 std::weak_ptr
,可以优化内存管理并确保树形结构的完整性。