🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ### 智能指针 智能指针是一个对象,他用来保存和管理指向堆对象的指针,他会在何时的时刻自动删除堆对象 常用的有: 1. Qt 中的 QPointer 2. 标准库中的 `std::shared_ptr/std::unique_ptr/std::weak_ptr` 3. Boost中的 shared_ptr ## std::shared_ptr / std::make_shared 语法 ``` get() 方法来获取原始指针 reset() 来减少一个引用计数 use_count() 查看一个对象的引用计数 ``` 使用`std::shared_ptr`仍然需要使用`new`来调用,这使得代码出现了某种程度上的不对称 ``` void foo(const std::shared_ptr<int>& unique) { (*unique)++; } int main() { std::shared_ptr<int> shared_ptr = std::make_shared<int>(10); foo(shared_ptr); std::cout << *shared_ptr<<"\n"; // 11 shared_ptr = std::make_shared<int>(20); foo(shared_ptr); std::cout << *shared_ptr; // 21 // share_ptr 被复用 } ``` ## std::unique_ptr `std::unique_ptr`是一种独占的智能指针,它禁止其他智能指针与其共享同一个对象,从而保证代码的安全 ``` std::unique_ptr<int> pointer = std::make_unique<int>(10); // make_unique 从 C++14 引入 std::unique_ptr<int> pointer2 = pointer; // 非法 ``` `make_unique`并不复杂,C++11 没有提供`std::make_unique`,可以自行实现: ``` template<typename T, typename ...Args> std::unique_ptr<T> make_unique( Args&& ...args ) { return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) ); } ``` 既然是独占,换句话说就是不可复制。但是,我们可以利用`std::move`将其转移给其他的`unique_ptr` ``` #include <iostream> #include <memory> struct Foo { Foo() { std::cout << "Foo::Foo" << std::endl; } ~Foo() { std::cout << "Foo::~Foo" << std::endl; } void foo() { std::cout << "Foo::foo" << std::endl; } }; void f(const Foo &) { std::cout << "f(const Foo&)" << std::endl; } int main() { std::unique_ptr<Foo> p1(std::make_unique<Foo>()); // p1 不空, 输出 if (p1) p1->foo(); { std::unique_ptr<Foo> p2(std::move(p1)); // p2 不空, 输出 f(*p2); // p2 不空, 输出 if(p2) p2->foo(); // p1 为空, 无输出 if(p1) p1->foo(); p1 = std::move(p2); // p2 为空, 无输出 if(p2) p2->foo(); std::cout << "p2 被销毁" << std::endl; } // p1 不空, 输出 if (p1) p1->foo(); // Foo 的实例会在离开作用域时被销毁 } ``` ### std::weak_ptr std::share_ptr 在相互应用的时候,也是无法释放内存的, 此时就要用到 std::weak_ptr bad ``` #include <iostream> #include <memory> class A; class B{ public: ~B() { std::cout << "B destory, a_ptr use_count:" << a_ptr.use_count() << "\n"; } std::shared_ptr<A> a_ptr; }; class A{ public: ~A() { std::cout << "A destory, b_ptr use_count:" << b_ptr.use_count() << "\n"; } std::shared_ptr<B> b_ptr; }; int main() { std::shared_ptr<A> a(new A()); std::shared_ptr<B> b(new B()); a->b_ptr=b; b->a_ptr=a; std::cout << "A:" << a.use_count() << "\n"; std::cout << "B" << b.use_count() << "\n"; } ``` good ``` class A{ public: ~A() { std::cout << "A destory, b_ptr use_count:" << b_ptr.use_count() << "\n"; } std::weak_ptr<B> b_ptr; }; ```