- std::unique_ptr(独占指针)
核心概念:霸道总裁。 「这个对象归我一个人所有,谁也别想复制。但我可以把它『转让』给别人,转让后我就不管了。」
include
include
struct Task {
int id;
Task(int i) : id(i) { std::cout << "Task " << id << " 創建\n"; }
~Task() { std::cout << "Task " << id << " 銷毀\n"; }
};
int main() {
// 1. 創建:推薦使用 std::make_unique (C++14 起) //用make_unique<>
std::unique_ptr
// 2. 訪問:像普通指針一樣使用 -> 和 *
std::cout << "當前任務 ID: " << taskPtr->id << "\n";
// 3. 獨占特性:
// std::unique_ptr<Task> p2 = taskPtr; // ❌ 報錯!禁止拷貝(複製)
// 4. 所有權轉移 (Move):
std::unique_ptr<Task> p2 = std::move(taskPtr); // ✅ 合法 //move(p1)
// 此時 taskPtr 變為空 (nullptr),p2 接管了對象
if (taskPtr == nullptr) std::cout << "taskPtr 已被掏空\n";
if (p2 != nullptr) std::cout << "p2 拿到所有權\n";
} // 作用域結束,p2 自動銷毀,Task 1 被釋放
- std::shared_ptr(共享指针)
核心概念:共享单车。 「这个对象我们可以一起用。每多一个人用,计数器就+1;走一个人,计数器-1。当最后一个人用完离开时,对象才销毁。」
include
include
struct Resource {
~Resource() { std::cout << "資源被釋放\n"; }
};
int main() {
// 1. 創建:推薦使用 std::make_shared (效率更高,內存分配一次完成)
std::shared_ptr
std::cout << "當前引用計數: " << ptr1.use_count() << "\n"; // 輸出 1
{
// 2. 共享:可以直接賦值拷貝
std::shared_ptr<Resource> ptr2 = ptr1;
std::cout << "ptr2 加入,引用計數: " << ptr1.use_count() << "\n"; // 輸出 2
// ptr1 和 ptr2 指向同一個對象,誰用都行
}
// 這裡 ptr2 離開作用域,計數 -1
std::cout << "ptr2 離開後,引用計數: " << ptr1.use_count() << "\n"; // 輸出 1
} // main 結束,ptr1 離開,計數歸 0 -> 資源被釋放
- std::weak_ptr(弱引用指针)
核心概念:暗中观察者(shared_ptr 的小跟班)。 「我看着这个对象,但我『不算人头』。即便我看着它,如果其他owner 都走了,对象照样销毁。我想用的时候,得先看看它还在不在。」
适用场景:
解决循环引用(最重要):A 指向B,B 指向A,导致双方计数器永远不为0,内存泄漏。
缓存机制:想访问对象但不想强占有它(如果对象还在就用,不在就算了)。
用法注意:weak_ptr没有重载->和*,不能直接操作对象。必须先调用.lock()升级为shared_ptr才能使用。
include
include
struct B; // 前置聲明
struct A {
std::shared_ptr ptrB; // A 強持有 B
~A() { std::cout << "A 釋放\n"; }
};
struct B {
// ❌ 如果這裡寫 std::shared_ptr ptrA; 會導致循環引用,內存洩漏!
std::weak_ptr ptrA; // ✅ 改用 weak_ptr,不增加 A 的引用計數
~B() { std::cout << "B 釋放\n"; }
};
int main() {
auto a = std::make_shared();
auto b = std::make_shared();
a->ptrB = b; // A 指向 B
b->ptrA = a; // B 弱引用 A (不增加 A 的計數)
// 演示 weak_ptr 如何使用數據
if (auto lockedPtr = b->ptrA.lock()) { // lock() 檢測 A 是否還活著 //用.lock()
std::cout << "從 B 中成功訪問 A\n";
}
} // main 結束:
// 1. a 變量銷毀。因為 b->ptrA 是 weak,不佔計數,所以 A 的計數歸零 -> A 析構。
// 2. A 析構導致 A->ptrB 銷毀 -> B 的計數歸零 -> B 析構。
// 完美釋放!
lecode232
//stack的应用
class MyQueue {
private:
std::stack
void reset(){
while(!stack_in.empty()){
stack_out.push(stack_in.top());
stack_in.pop();
}
}
public:
MyQueue() {
}
void push(int x) {
stack_in.push(x);
}
int pop() {
if(stack_out.empty()){
reset();
}
int x=stack_out.top();
stack_out.pop();
return x;
}
int peek() {
if(stack_out.empty()){
reset();
}
return stack_out.top();
}
bool empty() {
return stack_in.empty()&&stack_out.empty();
}
};
/**
- Your MyQueue object will be instantiated and called as such:
- MyQueue* obj = new MyQueue();
- obj->push(x);
- int param_2 = obj->pop();
- int param_3 = obj->peek();
- bool param_4 = obj->empty();
*/
lecode20
浙公网安备 33010602011771号