什么是智能指针?智能指针有什么作用?分为哪几种?各自有什么样的特点?
智能指针是C++中的一种对象,它像常规指针一样工作,但有更多的功能。最主要的是,智能指针通过自动管理内存来帮助防止内存泄露。它们在销毁对象时自动释放对象所占用的内存,从而使得内存管理更为安全和方便。
C++标准库提供了以下几种类型的智能指针:
std::auto_ptr
:这是C++98中的智能指针,但在C++11中已经被弃用。它的主要问题是所有权语义的设计不正确,当复制或赋值时,所有权会从一个指针转移给另一个指针,这可能会引发一些意外的问题。-
std::unique_ptr
:这是C++11引入的智能指针,它具有独占所有权语义,也就是说,在任何时候,一个std::unique_ptr
对象都是它所指向对象的唯一所有者。这使得std::unique_ptr
非常适合用于管理资源的唯一性,例如文件句柄,网络连接,或者自定义的资源。 -
std::shared_ptr
:这也是C++11引入的智能指针,它允许多个std::shared_ptr
对象共享对同一个对象的所有权。std::shared_ptr
使用引用计数来跟踪有多少个智能指针共享同一个对象,当最后一个std::shared_ptr
被销毁时,它会自动删除所指向的对象。std::shared_ptr
适用于需要多个指针共享所有权的场合,例如实现一个树或图数据结构。 -
std::weak_ptr
:这是一种特殊的智能指针,它是std::shared_ptr
的配套工具。std::weak_ptr
持有一个非持久的对象引用,不会增加引用计数。它主要用于防止std::shared_ptr
引发的循环引用问题。
以下是一个 std::unique_ptr
和 std::shared_ptr
的示例:
#include <memory>
struct Foo {
Foo() { std::cout << "Foo::Foo\n"; }
~Foo() { std::cout << "Foo::~Foo\n"; }
void bar() { std::cout << "Foo::bar\n"; }
};
void unique_ptr_example() {
std::unique_ptr<Foo> p1(new Foo); // p1 owns Foo
if (p1) p1->bar();
{
std::unique_ptr<Foo> p2(std::move(p1)); // now p2 owns Foo
f(p2.get());
p1 = std::move(p2); // ownership returns to p1
std::cout << "destroying p2...\n";
}
if (p1) p1->bar();
// Foo instance will be destroyed when p1 goes out of scope
}
void shared_ptr_example() {
std::shared_ptr<int> p1 = std::make_shared<int>(5);
std::shared_ptr<int> p2 = p1; // Both now own the memory.
std::cout << *p1 << std::endl; // prints "5"
*p2 = 10;
std::cout << *p1 << std::endl; // prints "10"
// Memory will be automatically deallocated when p1 and p2 goes out of scope
}
在这个例子中,你可以看到 std::unique_ptr
和 std::shared_ptr
如何自动管理内存,让你不必手动调用 delete
。