資源獲取是初始化

資源獲取初始化(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