请用代码举例说明智能指针shared_ptr、unique_ptr、weak_ptr各自实现原理与区别。
时间: 2023-07-18 18:03:50 浏览: 187
好的,以下是C++中三种智能指针的实现原理和区别。
首先,我们需要明确一下什么是智能指针。智能指针是一种C++中的类,它的行为类似于指针,但是它具有一些额外的功能,比如自动内存管理。智能指针能够自动释放所管理的对象,从而避免内存泄漏和野指针的问题。
下面我们分别介绍shared_ptr、unique_ptr、weak_ptr三种智能指针的实现原理和区别。
## shared_ptr
shared_ptr是一种引用计数智能指针,它的实现原理是通过使用引用计数来跟踪有多少个shared_ptr对象指向同一个对象。每当一个新的shared_ptr对象指向该对象时,引用计数就会增加1,当一个shared_ptr对象被销毁时,引用计数就会减少1。当引用计数变为0时,就表示没有任何shared_ptr对象指向该对象,此时该对象将被自动销毁。
shared_ptr的优点是可以共享资源,缺点是有可能出现循环引用的问题,导致内存泄漏。为了避免这个问题,C++11中引入了weak_ptr。
## unique_ptr
unique_ptr是一种独占式智能指针,它的实现原理是通过禁止拷贝和赋值来保证同一时间只有一个unique_ptr对象指向一个对象。当一个unique_ptr对象被销毁时,它所管理的对象也将会被销毁。为了更好地支持移动语义,C++11中引入了move语义,使得unique_ptr对象可以被移动而不是被复制。
unique_ptr的优点是可移植性好,可以避免循环引用的问题,缺点是不能共享资源。
## weak_ptr
weak_ptr是一种弱引用智能指针,它的实现原理是与shared_ptr配合使用。weak_ptr不会增加引用计数,它只是提供了对所指向对象的一个非拥有性的访问。当所指向的对象被销毁后,weak_ptr将自动失效。
weak_ptr的优点是可以避免循环引用的问题,缺点是不能访问所指向对象的成员变量和成员函数。如果需要访问所指向对象的成员变量和成员函数,需要将weak_ptr转换为shared_ptr。
下面是一个示例代码,展示了shared_ptr、unique_ptr、weak_ptr的使用方式:
```c++
#include <iostream>
#include <memory>
class A {
public:
A() { std::cout << "A()" << std::endl; }
~A() { std::cout << "~A()" << std::endl; }
void foo() { std::cout << "foo()" << std::endl; }
};
int main() {
// shared_ptr
std::shared_ptr<A> p1(new A());
std::shared_ptr<A> p2(p1);
std::cout << "p1.use_count() = " << p1.use_count() << std::endl;
std::cout << "p2.use_count() = " << p2.use_count() << std::endl;
// unique_ptr
std::unique_ptr<A> p3(new A());
// std::unique_ptr<A> p4(p3); // error: copy constructor is deleted
std::unique_ptr<A> p5(std::move(p3));
if (p3 == nullptr) {
std::cout << "p3 is nullptr" << std::endl;
}
// weak_ptr
std::shared_ptr<A> p6(new A());
std::weak_ptr<A> p7(p6);
std::cout << "p7.use_count() = " << p7.use_count() << std::endl;
if (auto p8 = p7.lock()) {
p8->foo();
} else {
std::cout << "p7 is expired" << std::endl;
}
return 0;
}
```
阅读全文