C++智能指针简介
什么是智能指针?
智能指针就像你的"智能小管家",帮你自动管理内存,不用再担心忘记释放内存导致泄漏的问题。
三种常用智能指针
unique_ptr
- 唯一管家
• 特点:一个对象只能有一个管家
• 不能复制,但可以"交接"(移动)
#include <memory>
#include <iostream>class Dog {
public:Dog(std::string n) : name(n) {}void bark() { std::cout << name << ":汪汪!" << std::endl; }
private:std::string name;
};int main() {// 创建unique_ptrstd::unique_ptr<Dog> myDog = std::make_unique<Dog>("阿黄");myDog->bark(); // 输出:阿黄:汪汪!// 不能这样复制!(报错)// auto otherDog = myDog; // 但可以这样"交接"(移动)auto newOwner = std::move(myDog);if(!myDog) {std::cout << "原主人已经没有狗了" << std::endl;}newOwner->bark(); // 输出:阿黄:汪汪!
}
shared_ptr
- 共享管家
• 特点:多个管家可以共同照顾同一个对象
• 通过计数知道有多少个管家在管理
#include <memory>
#include <iostream>class Cat {
public:Cat(std::string n) : name(n) {}void meow() { std::cout << name << ":喵喵~" << std::endl; }~Cat() { std::cout << name << "去喵星了" << std::endl; }
private:std::string name;
};int main() {// 创建shared_ptrstd::shared_ptr<Cat> cat1 = std::make_shared<Cat>("小白");// 复制 - 现在有两个管家std::shared_ptr<Cat> cat2 = cat1;cat1->meow(); // 输出:小白:喵喵~cat2->meow(); // 输出:小白:喵喵~std::cout << "管家数量: " << cat1.use_count() << std::endl; // 输出:2// 当一个管家离开cat1.reset();std::cout << "现在管家数量: " << cat2.use_count() << std::endl; // 输出:1
}
// cat2离开时输出:小白去喵星了
weak_ptr
- 观察员管家
• 特点:只观察不管理,不影响对象生命周期
• 需要时可以临时"转正"成shared_ptr
#include <memory>
#include <iostream>class Bird {
public:Bird(std::string n) : name(n) {}void fly() { std::cout << name << "在飞翔" << std::endl; }
private:std::string name;
};int main() {std::shared_ptr<Bird> spBird = std::make_shared<Bird>("小绿");std::weak_ptr<Bird> wpBird = spBird; // 创建观察员// 需要时转正if(auto temp = wpBird.lock()) {temp->fly(); // 输出:小绿在飞翔}spBird.reset(); // 主人不要鸟了if(wpBird.expired()) {std::cout << "小鸟已经飞走了" << std::endl;}
}
如何复制智能指针?
类型 | 能否复制 | 正确复制方式 | 特点 |
---|---|---|---|
unique_ptr | ❌ 不能 | std::move() | 移动后原指针变空 |
shared_ptr | ✅ 能 | 直接赋值 | 引用计数+1 |
weak_ptr | ✅ 能 | 直接赋值 | 不影响引用计数 |
建议
- 优先用
make_unique
和make_shared
创建 - 默认先用
unique_ptr
,需要共享再用shared_ptr
- 两个类互相包含时,记得用
weak_ptr
避免循环引用
备注
个人能力有限,有问题随时交流~~