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

162
ACMOJ-2090.hpp Normal file
View File

@ -0,0 +1,162 @@
#ifndef SRC_HPP
#define SRC_HPP
#include <initializer_list>
#include <stdexcept>
// 以上是你所需要的头文件,如果你想使用其它头文件,请询问助教
// 禁止使用 std::shared_ptr 与 std::any
namespace sjtu {
class any_ptr {
class Info_Base {
public:
int counter;
virtual ~Info_Base() {}
};
template <class T>
class Info : public Info_Base {
public:
T *ptr;
Info(T *ptr) : ptr(ptr) {}
~Info() override { delete ptr; }
};
Info_Base *info = nullptr;
public:
/**
* @brief 默认构造函数,行为应与创建空指针类似
*
*/
any_ptr() {}
/**
* @brief
* 拷贝构造函数,要求拷贝的层次为浅拷贝,即该对象与被拷贝对象的内容指向同一块内存
* @note 若将指针作为参数传入,则指针的生命周期由该对象管理
* @example
* any_ptr a = make_any_ptr(1);
* any_ptr b = a;
* a.unwrap<int> = 2;
* std::cout << b << std::endl; // 2
* @param other
*/
any_ptr(const any_ptr &other) {
info = other.info;
if (info) info->counter++;
}
template <class T>
any_ptr(T *ptr) {
info = new Info<T>(ptr);
info->counter = 1;
}
/**
* @brief
* 析构函数,注意若一块内存被多个对象共享,那么只有最后一个析构的对象需要释放内存
* @example
* any_ptr a = make_any_ptr(1);
* {
* any_ptr b = a;
* }
* std::cout << a << std::endl; // valid
* @example
* int *p = new int(1);
* {
* any_ptr a = p;
* }
* std::cout << *p << std::endl; // invalid
*
*/
~any_ptr() {
if (info) {
info->counter--;
if (info->counter == 0) {
delete info;
}
}
}
/**
* @brief
* 拷贝赋值运算符,要求拷贝的层次为浅拷贝,即该对象与被拷贝对象的内容指向同一块内存
* @note 应与指针拷贝赋值运算符的语义相近
* @param other
* @return any_ptr&
*/
any_ptr &operator=(const any_ptr &other) {
if (info) {
info->counter--;
if (info->counter == 0) {
delete info;
}
}
info = other.info;
if (info) info->counter++;
return *this;
}
template <class T>
any_ptr &operator=(T *ptr) {
if (info) {
info->counter--;
if (info->counter == 0) {
delete info;
}
}
info = new Info<T>(ptr);
info->counter = 1;
return *this;
}
/**
* @brief 获取该对象指向的值的引用
* @note 若该对象指向的值不是 T 类型,则抛出异常 std::bad_cast
* @example
* any_ptr a = make_any_ptr(1);
* std::cout << a.unwrap<int>() << std::endl; // 1
* @tparam T
* @return T&
*/
template <class T>
T &unwrap() {
Info<T> *info_t = dynamic_cast<Info<T> *>(info);
if (info_t)
return *(info_t->ptr);
else
throw std::bad_cast();
}
// 某一个 any_ptr 类对象可能为 const请你补充 unwrap 函数
template <class T>
const T &unwrap() const {
Info<T> *info_t = dynamic_cast<Info<T> *>(info);
if (info_t)
return *(info_t->ptr);
else
throw std::bad_cast();
}
};
/**
* @brief 由指定类型的值构造一个 any_ptr 对象
* @example
* any_ptr a = make_any_ptr(1);
* any_ptr v = make_any_ptr<std::vector<int>>(1, 2, 3);
* any_ptr m = make_any_ptr<std::map<int, int>>({{1, 2}, {3, 4}});
* @tparam T
* @param t
* @return any_ptr
*/
template <class T>
any_ptr make_any_ptr(const T &t) {
return any_ptr(new T(t));
}
// 某些 any_ptr 类对象可能由不定长参数或初始化列表构造,请你参照上方的 example
// 补充 make_any_ptr 函数,我们会有一个特殊的测试点测试你的程序是否完成要求
template <class T, class... Args>
any_ptr make_any_ptr(Args... args) {
return any_ptr(new T(std::forward<Args>(args)...));
}
} // namespace sjtu
#endif