This commit is contained in:
2023-12-23 22:23:48 +08:00
commit 43ced8bd2a
58 changed files with 5702 additions and 0 deletions

101
ACMOJ-2095.hpp Normal file
View File

@ -0,0 +1,101 @@
#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