C++ 使用智能指針 shared_ptr、unique_ptr、make_shared 更安全管理內(nèi)存

有使用 C++ 做開發(fā)的童鞋應(yīng)該都經(jīng)歷過被 指針 折磨,使用指針的使用需要保證 new 和 delete 對(duì)齊,如果不注意使用很容易出現(xiàn)野指針、空指針和內(nèi)存泄漏等風(fēng)險(xiǎn)。我們應(yīng)該盡量避免使用指針,如果一定要用指針,推薦使用 C++ STL 提供智能指針,STL 的智能指針有 shared_ptr 和 unique_ptr。

shared_ptr

shared_ptr 是基于計(jì)數(shù)器技術(shù),一個(gè)對(duì)象可以被多個(gè) shared_ptr 指向,多個(gè) shared_ptr 共同維護(hù)一個(gè)共享的的引用計(jì)數(shù)器,當(dāng)計(jì)數(shù)器為 0 的時(shí)候自動(dòng)釋放對(duì)象,不需要通過delete進(jìn)行釋放。

class User {
public:
    string name;
    User(string name) {
        this->name = name;
        cout << "User:" << name << endl;
    }
    void say() {
        cout << name << endl;
    }
    ~User() {
        cout << "~User:" << name << endl;
    }
};

創(chuàng)建方式一

shared_ptr<User> user(new User("shared_ptr"));

創(chuàng)建方式二(推薦)

shared_ptr<User> user = make_shared<User>("make_shared");

使用指針

cout<<user->name<<endl;
user->say();

多個(gè) shared_ptr 指向一個(gè)對(duì)象

錯(cuò)誤?:多個(gè) shared_ptr 不能指向同一個(gè)原生對(duì)象

User *u = new User("shared_ptr");
shared_ptr<User> user1(u);
shared_ptr<User> user2(u); // 錯(cuò)誤,不被允許

正確?:可以通過拷貝方式實(shí)現(xiàn)

shared_ptr<User> user1(new User("shared_ptr"));
shared_ptr<User> user2 = user1;

指針傳遞

// 推薦寫法
void handle1(const shared_ptr<User> &user) {
    user->say();
}
void handle2(const shared_ptr<User> user) {
    user->say();
}
int main(){
  shared_ptr<User> user = make_shared<User>("make_shared");
  handle1(user);
  handle2(user);
  return 0;
}

unique_ptr

unique_ptr 是獨(dú)享的智能指針,一個(gè)對(duì)象只允許被一個(gè) unique_ptr 指向。

正確?

unique_ptr<User> user(new User("unique_ptr"));

正確?:推薦使用 make_unique

unique_ptr<User> user = make_unique<User>("unique_ptr");

錯(cuò)誤?:一個(gè)對(duì)象只允許被一個(gè) unique_ptr 指向。

User *u = new User("shared_ptr");
unique_ptr<User> user1(u);
unique_ptr<User> user2(u);

錯(cuò)誤?:unique_ptr 不支持拷貝

User *u = new User("shared_ptr");
unique_ptr<User> user1(u);
unique_ptr<User> user2 = user1;

指針傳遞

只允許通過值引用或者指針方式,不支持值傳遞,也可以通過 move 實(shí)現(xiàn)轉(zhuǎn)移。

void handle1(const unique_ptr<User> &user) {
    user->say();
}
void handle2(const unique_ptr<User> user) {
    user->say();
}
int main(){
  unique_ptr<User> user(new User("unique_ptr"));
  handle1(user);
  // 錯(cuò)誤 handle2(user);
  handle2(move(user));
  return 0;
}

指針轉(zhuǎn)移

智能指針單獨(dú)使用是比較簡單的,不需要手動(dòng)對(duì)指針進(jìn)行釋放。如果需要在 vector 進(jìn)行使用,也是需要注意。

vector<unique_ptr<User>> users;
unique_ptr<User> user(new User("unique_ptr"));
users.push_back(move(user));
users[0]->say();

完整示例代碼

#include <iostream>
#include <vector>

using namespace std;

class User {
public:
    string name;
    User(string name) {
        this->name = name;
        cout << "User:" << name << endl;
    }
    void say() {
        cout << name << endl;
    }
    ~User() {
        cout << "~User:" << name << endl;
    }
};
void handle0(const shared_ptr<User> &user) {
    user->say();
}
// 允許多個(gè) shared_ptr 指向同一個(gè)對(duì)象
void handle1(const shared_ptr<User> user) {
    user->say();
}
// unique_ptr 不允許使用值傳遞,因?yàn)槭仟?dú)享的
void handle2(const unique_ptr<User> &user) {
    user->say();
}
int main() {
    shared_ptr<User> shared1(new User("shared_ptr"));
    // 多個(gè) shared_ptr 不能指向同一個(gè)原生對(duì)象,如果需要多個(gè)shared_ptr指向同一個(gè)對(duì)象可以通過一下方式實(shí)現(xiàn)
    const shared_ptr<User> shared2 = shared1;

    // 推薦使用 make_shared 方式創(chuàng)建 shared_ptr
    shared_ptr<User> make_shared1 = make_shared<User>("make_shared");

    unique_ptr<User> unique1(new User("unique_ptr"));
    unique_ptr<User> unique2 = make_unique<User>("make_unique");

    // 不允許 unique_ptr<User> unique2 = unique1;
    shared1->say();
    make_shared1->say();
    unique1->say();
    handle0(shared2);
    handle1(shared2);
    handle1(make_shared1);
    handle2(unique1);
    handle2(unique2);

    vector<unique_ptr<User>> users;
    users.push_back(move(unique1));
    users[0]->say();
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容