有使用 C++ 做开发的童鞋应该都经历过被 指针
折磨,使用指针的使用需要保证 new 和 delete 对齐,如果不注意使用很容易出现野指针、空指针和内存泄漏等风险。我们应该尽量避免使用指针,如果一定要用指针,推荐使用 C++ STL 提供智能指针,STL 的智能指针有 shared_ptr 和 unique_ptr。
shared_ptr
shared_ptr 是基于计数器技术,一个对象可以被多个 shared_ptr 指向,多个 shared_ptr 共同维护一个共享的的引用计数器,当计数器为 0 的时候自动释放对象,不需要通过delete进行释放。
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;
}
};
创建方式一
shared_ptr<User> user(new User("shared_ptr"));
创建方式二(推荐)
shared_ptr<User> user = make_shared<User>("make_shared");
使用指针
cout<<user->name<<endl;
user->say();
多个 shared_ptr 指向一个对象
错误❌:多个 shared_ptr 不能指向同一个原生对象
User *u = new User("shared_ptr");
shared_ptr<User> user1(u);
shared_ptr<User> user2(u); // 错误,不被允许
正确✅:可以通过拷贝方式实现
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 是独享的智能指针,一个对象只允许被一个 unique_ptr 指向。
正确✅
unique_ptr<User> user(new User("unique_ptr"));
正确✅:推荐使用 make_unique
unique_ptr<User> user = make_unique<User>("unique_ptr");
错误❌:一个对象只允许被一个 unique_ptr 指向。
User *u = new User("shared_ptr");
unique_ptr<User> user1(u);
unique_ptr<User> user2(u);
错误❌:unique_ptr 不支持拷贝
User *u = new User("shared_ptr");
unique_ptr<User> user1(u);
unique_ptr<User> user2 = user1;
指针传递
只允许通过值引用或者指针方式,不支持值传递,也可以通过 move 实现转移。
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);
// 错误 handle2(user);
handle2(move(user));
return 0;
}
指针转移
智能指针单独使用是比较简单的,不需要手动对指针进行释放。如果需要在 vector 进行使用,也是需要注意。
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();
}
// 允许多个 shared_ptr 指向同一个对象
void handle1(const shared_ptr<User> user) {
user->say();
}
// unique_ptr 不允许使用值传递,因为是独享的
void handle2(const unique_ptr<User> &user) {
user->say();
}
int main() {
shared_ptr<User> shared1(new User("shared_ptr"));
// 多个 shared_ptr 不能指向同一个原生对象,如果需要多个shared_ptr指向同一个对象可以通过一下方式实现
const shared_ptr<User> shared2 = shared1;
// 推荐使用 make_shared 方式创建 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;
}