作者:
yam276 ('_')
2025-03-09 01:45:04※ 引述《zenice (阿排)》之銘言:
: → yam276: 用智慧指標啊 用了就回不去了 03/09 01:40
: → zenice: 作業不讓用 對ㄚ 03/09 01:41
: → yam276: 那寫個自幹資源管理class 應該沒很難 03/09 01:41
: → yam276: template可以用嗎 03/09 01:41
: → zenice: 應該可以 我下次寫 這次bug改完交出去了 03/09 01:42
讓AI大師幫你自幹一個了
應該比我寫的好很多
AutoPtr.h
#pragma once
// 自定義資源管理類別,類似 std::unique_ptr,但不依賴智能指標
template <typename T>
class AutoPtr {
public:
// 構造函數,接受裸指標
explicit AutoPtr(T* ptr = nullptr) noexcept : ptr_(ptr) {}
// 析構函數,自動釋放資源
~AutoPtr() noexcept {
delete ptr_;
}
// 禁止複製構造
AutoPtr(const AutoPtr&) = delete;
AutoPtr& operator=(const AutoPtr&) = delete;
// 允許移動構造
AutoPtr(AutoPtr&& other) noexcept : ptr_(other.ptr_) {
other.ptr_ = nullptr; // 轉移所有權,源對象置空
}
// 允許移動賦值
AutoPtr& operator=(AutoPtr&& other) noexcept {
if (this != &other) {
delete ptr_; // 先釋放原有的資源
ptr_ = other.ptr_;
other.ptr_ = nullptr; // 轉移所有權
}
return *this;
}
// 獲取裸指標(const版本)
T* get() const noexcept {
return ptr_;
}
// 解引用操作符
T& operator*() const noexcept {
return *ptr_;
}
// 成員訪問操作符
T* operator->() const noexcept {
return ptr_;
}
// 檢查是否為空
bool is_null() const noexcept {
return ptr_ == nullptr;
}
// 釋放資源並重置為空
void reset(T* ptr = nullptr) noexcept {
if (ptr_ != ptr) {
delete ptr_;
ptr_ = ptr;
}
}
// 交換兩個AutoPtr的資源
void swap(AutoPtr& other) noexcept {
T* tmp = ptr_;
ptr_ = other.ptr_;
other.ptr_ = tmp;
}
private:
T* ptr_; // 管理的裸指標
};
// 非成員函數:交換兩個AutoPtr
template <typename T>
void swap(AutoPtr<T>& lhs, AutoPtr<T>& rhs) noexcept {
lhs.swap(rhs);
}
用法
sample.cpp
#include <iostream>
// 一個簡單的測試類別
struct MyClass {
MyClass() { std::cout << "MyClass constructed\n"; }
~MyClass() { std::cout << "MyClass destructed\n"; }
};
int main() {
// 使用AutoPtr管理單個對象
{
AutoPtr<MyClass> ptr(new MyClass());
// 自動釋放,無需手動delete
} // 離開作用域時,MyClass被自動析構
// 使用AutoPtr管理數組
{
AutoPtr<MyClass[]> arr(new MyClass[3]);
// 自動釋放數組,無需手動delete[]
}
// 移動語義
{
AutoPtr<MyClass> ptr1(new MyClass());
AutoPtr<MyClass> ptr2 = std::move(ptr1); // 移動構造
if (ptr1.is_null()) {
std::cout << "ptr1 is null after move\n";
}
}
// 重置資源
{
AutoPtr<MyClass> ptr(new MyClass());
ptr.reset(new MyClass()); // 釋放舊資源,接管新資源
}
return 0;
}