dapaogege

导航

 
  1. 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 taskPtr = std::make_unique(1);

// 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 被釋放

  1. std::shared_ptr(共享指针)
    核心概念:共享单车。 「这个对象我们可以一起用。每多一个人用,计数器就+1;走一个人,计数器-1。当最后一个人用完离开时,对象才销毁。」

include

include

struct Resource {
~Resource() { std::cout << "資源被釋放\n"; }
};

int main() {
// 1. 創建:推薦使用 std::make_shared (效率更高,內存分配一次完成)
std::shared_ptr ptr1 = std::make_shared();

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 -> 資源被釋放

  1. 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 stack_in,stack_out;
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

posted on 2025-12-24 16:16  dapaogege  阅读(1)  评论(0)    收藏  举报