Files
SH-Quizzes/ACMOJ-2095.hpp
2023-12-23 22:23:48 +08:00

101 lines
3.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <new>
#include <utility>
// 你不可以使用其他任何头文件
namespace sjtu {
/**
* @brief 一个可以在离开作用域之后自动归还内存的指针。
* unique_ptr <_Tp> 行为应该和普通指针 _Tp * 几乎一致。
* @tparam _Tp 模板参数,指针指向的类型。
*/
template <typename _Tp>
class unique_ptr {
private:
// 你可以自由地增加成员变量和成员函数
_Tp *ptr=nullptr;
public:
// 构造一个空的指针 (nullptr)
unique_ptr() : ptr(nullptr){}
// 同一个指针不能被多个 unique_ptr 指向
unique_ptr(const unique_ptr &) = delete;
// 移动构造函数。移交所有权。
// 注意移交后要把 other 置空。
unique_ptr(unique_ptr &&other) {
ptr = other.ptr;
other.ptr = nullptr;
}
// 析构函数。释放指针指向的内存。
// 需要注意delete nullptr 是安全的。
~unique_ptr() { delete ptr; }
// 同一个指针不能被多个 unique_ptr 指向
unique_ptr &operator=(const unique_ptr &) = delete;
// 移动赋值运算符。移交所有权。
// 注意移交后要把 other 置空。
unique_ptr &operator=(unique_ptr &&other) {
if (this == &other) return *this;
delete ptr;
ptr = other.ptr;
other.ptr = nullptr;
return *this;
}
// 接管一个普通 _Tp 类型的指针的所有权
explicit unique_ptr(_Tp *address) : ptr(address) {}
// 重置为空指针。同时释放指针指向的内存。
void reset() {
delete ptr;
ptr = nullptr;
}
// 转移所有权,返回指针指向的对象的地址
// 同时,自己要置空。
_Tp *release() {
_Tp *ptr_tmp = ptr;
ptr = nullptr;
return ptr_tmp;
}
// 返回指针指向的对象的地址
// 所有权不转移。
_Tp *get() const noexcept { return ptr; }
// 重载 * 运算符(解引用),返回指针指向的对象的引用
_Tp &operator*() noexcept { return *ptr; }
// 重载 -> 运算符(成员访问),返回指针指向的对象的地址
_Tp *operator->() noexcept { return ptr; }
};
// 对于一个 unique_ptr你最多只能存一个指针
static_assert(sizeof(unique_ptr<int>) <= sizeof(void *));
// // 创建一个 unique_ptr指向一个用 new 分配的 _Tp 对象
// template <typename _Tp>
// unique_ptr <_Tp> make_unique(const _Tp &val)
// {
// return std::move(unique_ptr<_Tp>(new _Tp(val)));
// }
// Bonus: (不作为考察内容)
// (如果写了,请删除上面的这个 make_unique)
// (否则,请删除下面的这个 make_unique)
// 可变长参数列表 + 万能引用
// 创建一个 unique_ptr指向一个用 new 分配的 _Tp 对象
// 参数列表长度可变,且有左值引用和右值引用两种版本
// 当传入左值 T & Args 类型被推导为 T &
// 当传入右值 T &&Args 类型被推导为 T
// 你需要了解如何用 std::forward 实现完美转发
template <typename _Tp, typename... Args>
unique_ptr<_Tp> make_unique(Args &&...args) {
return std::move(unique_ptr<_Tp>(new _Tp(std::forward<Args>(args)...)));
}
} // namespace sjtu