在上篇文章中提到 C++ 11 中,智能指针主要包括std::unique_ptr
、std::shared_ptr
和std::weak_ptr
,每种智能指针都有其特定的用途和使用场景。
下面我们通过示例代码来逐一说明这几种智能指针的用法。
std::unique_ptr
std::unique_ptr
提供独占所有权的智能指针。一旦某个std::unique_ptr
拥有了某个对象,就没有其他智能指针可以同时拥有该对象。这种特性使得std::unique_ptr
非常适合用于管理资源的生命周期,如动态分配的内存、文件句柄等。
#include <memory>
#include <iostream>
class Example {
public:
Example() { std::cout << "Example created\n"; }
~Example() { std::cout << "Example destroyed\n"; }
};
int main() {
std::unique_ptr<Example> ptr = std::make_unique<Example>();
// 使用ptr->doSomething()访问成员函数
// 无需手动删除,当ptr离开作用域时,Example对象会自动被销毁
return 0;
}
因为用到了 std::make_unique
函数,这段代码需要支持 C++14 的编译器才能编译。
输出:
Example created
Example destroyed
std::shared_ptr
std::shared_ptr
提供共享所有权的智能指针。多个std::shared_ptr
可以同时拥有同一个对象,对象的生命周期会持续到最后一个拥有它的std::shared_ptr
被销毁或重置。std::shared_ptr
通常用于需要共享资源的情况。
#include <memory>
#include <iostream>
class Example {
public:
Example() { std::cout << "Example created\n"; }
~Example() { std::cout << "Example destroyed\n"; }
};
void useShared(std::shared_ptr<Example> sptr) {
// 使用sptr
}
int main() {
std::shared_ptr<Example> ptr1 = std::make_shared<Example>();
std::shared_ptr<Example> ptr2 = ptr1; // ptr1和ptr2共享对象
useShared(ptr2);
// 当ptr1和ptr2都离开作用域时,对象会自动被销毁
return 0;
}
这里的输出和上面的代码是一样的:
Example created
Example destroyed
std::weak_ptr
std::weak_ptr
是一种非拥有型智能指针,用于指向一个由std::shared_ptr
管理的对象,但不会增加对象的引用计数。std::weak_ptr
主要用于解决std::shared_ptr
的循环引用问题。
#include <memory>
#include <iostream>
class Child; // 前向声明
class Parent {
public:
std::shared_ptr<Child> child;
~Parent() { std::cout << "Parent destroyed\n"; }
};
class Child {
public:
std::weak_ptr<Parent> parent; // 使用weak_ptr避免循环引用
~Child() { std::cout << "Child destroyed\n"; }
};
int main() {
std::shared_ptr<Parent> ptr1 = std::make_shared<Parent>();
std::shared_ptr<Child> ptr2 = std::make_shared<Child>();
ptr1->child = ptr2;
ptr2->parent = ptr1;
// 当ptr1和ptr2都离开作用域时,即使它们互相引用,也能正确销毁
return 0;
}
输出:
Parent destroyed
Child destroyed
通过这些示例,可以看到不同类型的智能指针是如何在
C++ 中使用的,以及它们各自的特点和适用场景。智能指针是现代 C++ 编程中管理资源和避免内存泄露的重要工具。