c++智能指针是一种封装了原始指针的类对象,可以实现自动管理内存的功能,避免手动new和delete造成的内存泄漏或重复释放等问题。
c++智能指针有三种类型,分别是:
std::unique_ptr
:独占式智能指针,表示对内存的唯一所有权,不能被拷贝或赋值,只能通过移动语义转移所有权。适用于需要确保内存只有一个拥有者的场景,例如函数返回值、局部变量、类成员等。std::shared_ptr
:共享式智能指针,表示对内存的共享所有权,可以被拷贝或赋值,内部使用引用计数来记录内存的使用情况,当引用计数为零时,自动释放内存。适用于需要多个拥有者共同使用内存的场景,例如容器、动态数组、链表等。std::weak_ptr
:弱式智能指针,表示对内存的非拥有性引用,不能直接访问内存,只能通过lock()
方法获得一个std::shared_ptr
来访问内存,不影响引用计数。适用于需要观察或监视内存的场景,例如解决循环引用的问题、缓存数据等。
下面是一些c++智能指针的使用案例和场景的示例代码:
// 使用std::unique_ptr作为函数返回值,避免裸指针的内存泄漏
std::unique_ptr<int> create_int(int value) {return std::make_unique<int>(value); // 使用make_unique创建一个std::unique_ptr
}void use_int() {auto p = create_int(42); // 使用auto接收返回值,避免写出冗长的类型名std::cout << *p << std::endl; // 使用*解引用访问内存// 函数结束时,p自动析构,释放内存
}// 使用std::shared_ptr作为类成员,实现多个对象共享同一块内存
class Person {
private:std::string name_;int age_;std::shared_ptr<Person> friend_; // 使用std::shared_ptr作为类成员,表示与另一个Person对象共享内存
public:Person(const std::string& name, int age) : name_(name), age_(age) {}void make_friend(const std::shared_ptr<Person>& p) {friend_ = p; // 拷贝赋值,增加引用计数}void show_info() const {std::cout << "name: " << name_ << ", age: " << age_ << std::endl;if (friend_) {std::cout << "friend: " << friend_->name_ << std::endl;}}~Person() {std::cout << name_ << " is destructed" << std::endl;}
};void use_person() {auto alice = std::make_shared<Person>("Alice", 20); // 使用make_shared创建一个std::shared_ptrauto bob = std::make_shared<Person>("Bob", 21);alice->make_friend(bob); // Alice和Bob成为朋友,共享内存bob->make_friend(alice);alice->show_info();bob->show_info();// 函数结束时,alice和bob自动析构,引用计数减一,当引用计数为零时,释放内存
}
// 使用std::weak_ptr解决循环引用的问题
class Node {
private:int value_;std::shared_ptr<Node> next_; // 使用std::shared_ptr表示下一个节点的指针std::weak_ptr<Node> prev_; // 使用std::weak_ptr表示前一个节点的指针,避免循环引用
public:Node(int value) : value_(value) {}void set_next(const std::shared_ptr<Node>& next) {next_ = next;next->prev_ = std::weak_ptr<Node>(shared_from_this()); // 使用shared_from_this()获得当前对象的std::shared_ptr,然后转换为std::weak_ptr赋值给next的prev_}void show_info() const {std::cout << "value: " << value_ << std::endl;if (next_) {std::cout << "next: " << next_->value_ << std::endl;}if (auto p = prev_.lock()) { // 使用lock()方法获得一个std::shared_ptr,如果内存还存在,则可以访问,否则返回空指针std::cout << "prev: " << p->value_ << std::endl;}}~Node() {std::cout << value_ << " is destructed" << std::endl;}
};void use_node() {auto head = std::make_shared<Node>(1); // 创建一个头节点auto tail = std::make_shared<Node>(2); // 创建一个尾节点head->set_next(tail); // 设置头节点的下一个节点为尾节点,尾节点的前一个节点为头节点head->show_info();tail->show_info();// 函数结束时,head和tail自动析构,由于使用了std::weak_ptr,没有循环引用,内存可以正常释放
}