此小点内容来源于:豆包AI
#include <iostream>
#include <memory>
// 自定义类
class MyClass {
public:
MyClass() { std::cout << "MyClass constructor" << std::endl; }
~MyClass() { std::cout << "MyClass destructor" << std::endl; }
void doSomething() { std::cout << "Doing something..." << std::endl; }
};
class B;
class A {
public:
std::shared_ptr<B> bPtr;
~A() { std::cout << "A destructor" << std::endl; }
};
class B {
public:
std::weak_ptr<A> aPtr; // 使用 weak_ptr 避免循环引用
~B() { std::cout << "B destructor" << std::endl; }
};
void uniquePtrExample() {
// 创建一个 unique_ptr 指向 MyClass 对象
std::unique_ptr<MyClass> uniquePtr = std::make_unique<MyClass>();
// 调用对象的成员函数
uniquePtr->doSomething();
// unique_ptr 不能被复制,但可以转移所有权
// std::unique_ptr<MyClass> anotherPtr = uniquePtr; // 错误,不能复制
std::unique_ptr<MyClass> anotherPtr = std::move(uniquePtr);
if (!uniquePtr) {
std::cout << "uniquePtr is empty after move" << std::endl;
}
if (anotherPtr) {
anotherPtr->doSomething();
}
}
void sharedPtrExample() {
// 创建一个 shared_ptr 指向 MyClass 对象
std::shared_ptr<MyClass> sharedPtr1 = std::make_shared<MyClass>();
std::cout << "Shared pointer 1 use count: " << sharedPtr1.use_count() << std::endl;
// 复制 shared_ptr,引用计数增加
std::shared_ptr<MyClass> sharedPtr2 = sharedPtr1;
std::cout << "Shared pointer 1 use count after copy: " << sharedPtr1.use_count() << std::endl;
std::cout << "Shared pointer 2 use count: " << sharedPtr2.use_count() << std::endl;
// 调用对象的成员函数
sharedPtr2->doSomething();
// 释放一个 shared_ptr,引用计数减少
sharedPtr2.reset();
std::cout << "Shared pointer 1 use count after reset sharedPtr2: " << sharedPtr1.use_count() << std::endl;
}
void weakPtrExample() {
std::shared_ptr<A> a = std::make_shared<A>();
std::shared_ptr<B> b = std::make_shared<B>();
a->bPtr = b;
b->aPtr = a;
std::cout << "A use count: " << a.use_count() << std::endl;
std::cout << "B use count: " << b.use_count() << std::endl;
// 当 a 和 b 离开作用域时,对象会被正确销毁
}
int main() {
std::cout << "=== Unique Ptr Example ===" << std::endl;
uniquePtrExample();
std::cout << std::endl;
std::cout << "=== Shared Ptr Example ===" << std::endl;
sharedPtrExample();
std::cout << std::endl;
std::cout << "=== Weak Ptr Example ===" << std::endl;
weakPtrExample();
std::cout << std::endl;
return 0;
}
在 C++ 里,手动管理动态分配的内存容易引发内存泄漏、悬空指针等问题。智能指针作为一种类模板,能有效管理动态分配的内存,避免这些问题的出现。C++ 标准库提供了三种主要的智能指针:std::unique_ptr
、std::shared_ptr
和 std::weak_ptr
。
std::unique_ptr
std::unique_ptr
属于独占式智能指针,它对所指向的对象拥有唯一的所有权。一旦 std::unique_ptr
被销毁,其指向的对象也会随之被自动销毁。
在 uniquePtrExample
函数中:
- 借助
std::make_unique
创建了一个std::unique_ptr
,它指向MyClass
的一个对象。 - 调用
doSomething
方法来使用这个对象。 - 尝试复制
std::unique_ptr
会引发编译错误,因为它不允许复制,不过可以使用std::move
转移所有权。 - 转移所有权之后,原
std::unique_ptr
变为空。
std::shared_ptr
std::shared_ptr
是共享式智能指针,多个 std::shared_ptr
能够指向同一个对象。它采用引用计数来管理对象的生命周期,当引用计数变为 0 时,对象就会被销毁。
在 sharedPtrExample
函数中:
- 利用
std::make_shared
创建了一个std::shared_ptr
,它指向MyClass
的一个对象。 - 通过
use_count
方法可以查看当前的引用计数。 - 复制
std::shared_ptr
会使引用计数增加。 - 调用
reset
方法可以释放std::shared_ptr
,从而使引用计数减少。
std::weak_ptr
std::weak_ptr
是弱引用智能指针,它不拥有对象的所有权,只是对 std::shared_ptr
所管理的对象进行弱引用。std::weak_ptr
主要用于解决 std::shared_ptr
的循环引用问题。
在 weakPtrExample
函数中:
- 定义了
A
和B
两个类,其中A
类包含一个std::shared_ptr<B>
成员,B
类包含一个std::weak_ptr<A>
成员。 - 创建了
A
和B
的std::shared_ptr
对象,并相互引用。 - 由于
B
类使用了std::weak_ptr
,所以不会出现循环引用,当a
和b
离开作用域时,对象能够被正确销毁。