c++智能指针的使用官方参考 普通指针的烦恼:内存泄漏,多次释放,提前释放 智能指针 负责自动释放所指向的对象。 三种智能指针 shared_ptr,unique_ptr,weak_ptr; 将shared_ptr存放在一个容器中,不再需要它的时候,要erase掉。 allocator负责封装堆内存管理的对象,它们在整个标准库中使用,特别是STL容器使用它们来管理容器内部的所有内存分配,大部份情况下,程序员不用理会,标准容器使用默认的分配器称为std :: allocator。 shared_ptrshared_ptr 多个指针指向相同的对象; 使用引用计数,引用计数是线程安全的,但是对象的读写需要加锁。 不可以直接将指针直接赋值给一个智能指针,因为指针指针是一个类。 get获取原始指针 最大的陷阱就是循环引用,这会导致内存无法正确释放,导致内存泄漏 #include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>
struct Base
{
Base() { std::cout << " Base::Base()\n"; }
~Base() { std::cout << " Base::~Base()\n"; }
};
struct Derived: public Base
{
Derived() { std::cout << " Derived::Derived()\n"; }
~Derived() { std::cout << " Derived::~Derived()\n"; }
};
void thr(std::shared_ptr<Base> p)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::shared_ptr<Base> lp = p;
{
static std::mutex io_mutex;
std::lock_guard<std::mutex> lk(io_mutex);
std::cout << "local pointer in a thread:\n"
<< " lp.get() = " << lp.get()
<< ", lp.use_count() = " << lp.use_count() << '\n';
}
}
int main()
{
std::shared_ptr<Base> p = std::make_shared<Derived>();
std::cout << "Created a shared Derived (as a pointer to Base)\n"
<< " p.get() = " << p.get()
<< ", p.use_count() = " << p.use_count() << '\n';
std::thread t1(thr, p), t2(thr, p), t3(thr, p);
p.reset();
std::cout << "Shared ownership between 3 threads and released\n"
<< "ownership from main:\n"
<< " p.get() = " << p.get()
<< ", p.use_count() = " << p.use_count() << '\n';
t1.join(); t2.join(); t3.join();
std::cout << "All threads completed, the last one deleted Derived\n";
}
可能的输出: Base::Base()
Derived::Derived()
Created a shared Derived (as a pointer to Base)
p.get() = 0x2299b30, p.use_count() = 1
Shared ownership between 3 threads and released
ownership from main:
p.get() = 0, p.use_count() = 0
local pointer in a thread:
lp.get() = 0x2299b30, lp.use_count() = 5
local pointer in a thread:
lp.get() = 0x2299b30, lp.use_count() = 3
local pointer in a thread:
lp.get() = 0x2299b30, lp.use_count() = 2
Derived::~Derived()
Base::~Base()
All threads completed, the last one deleted Derived
weak_ptr是为了配合shared_ptr而引入的一种智能指针,没有重载operator*和->,它的最大作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况。 weak_ptr可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源的观测权。但weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。 成员函数expired()的功能等价于use_count()==0, weak_ptr可以使用一个非常重要的成员函数lock()从被观测的shared_ptr获得一个可用的shared_ptr对象 #include <iostream>
#include <memory>
std::weak_ptr<int> gw;
void observe()
{
std::cout << "use_count == " << gw.use_count() << ": ";
if (auto spt = gw.lock()) {
std::cout << *spt << "\n";
}
else {
std::cout << "gw is expired\n";
}
}
int main()
{
{
auto sp = std::make_shared<int>(42);
gw = sp;
observe();
}
observe();
}
输出: use_count == 1: 42
use_count == 0: gw is expired
|