资源获取是初始化

资源获取初始化(RAII)是资源管理中常见的习惯用语。在动态内存的情况下,它使用智能指针来完成资源管理。使用 RAII 时,立即将获得的资源授予智能指针或等效资源管理器。资源只能通过此管理器访问,因此管理员可以跟踪各种操作。例如,当 std::auto_ptr 超出范围或以其他方式删除时,std::auto_ptr 会自动释放其相应的资源。

#include <memory>
#include <iostream>
using namespace std;

int main() {
    {
        auto_ptr ap(new int(5)); // dynamic memory is the resource
        cout << *ap << endl; // prints 5
    } // auto_ptr is destroyed, its resource is automatically freed
}

Version >= C++ 11

std::auto_ptr 的主要问题是如果不转让所有权就无法复制:

#include <memory>
#include <iostream>
using namespace std;

int main() {
    auto_ptr ap1(new int(5));
    cout << *ap1 << endl; // prints 5
    auto_ptr ap2(ap1); // copy ap2 from ap1; ownership now transfers to ap2
    cout << *ap2 << endl; // prints 5
    cout << ap1 == nullptr << endl; // prints 1; ap1 has lost ownership of resource
}

由于这些奇怪的复制语义,std::auto_ptr 不能用于容器等。这样做的原因是为了防止两次删除内存:如果有两个 auto_ptrs 具有相同资源的所有权,它们都会在它们被销毁时尝试释放它。释放已经释放的资源通常会导致问题,因此防止它是很重要的。但是,std::shared_ptr 有一种避免这种情况的方法,而不是在复制时转移所有权:

#include <memory>
#include <iostream>
using namespace std;

int main() {
    shared_ptr sp2;
    {
        shared_ptr sp1(new int(5)); // give ownership to sp1
        cout << *sp1 << endl; // prints 5
        sp2 = sp1; // copy sp2 from sp1; both have ownership of resource
        cout << *sp1 << endl; // prints 5
        cout << *sp2 << endl; // prints 5
    } // sp1 goes out of scope and is destroyed; sp2 has sole ownership of resource
    cout << *sp2 << endl;        
} // sp2 goes out of scope; nothing has ownership, so resource is freed