写一个c++类any用于接收任意类型并提供有用的函数
以下是一个示例的C++类Any,它可以接收任意类型的对象,并提供了一些有用的函数:
#include <iostream>
#include <typeinfo>
#include <memory>
class Any {
public:
Any() : data(nullptr) {}
template <typename T>
Any(const T& value) : data(std::make_shared<Holder<T>>(value)) {}
Any(const Any& other) : data(other.data->clone()) {}
Any& operator=(const Any& other) {
data = other.data->clone();
return *this;
}
template<typename T>
Any& operator=(const T& value) {
data = std::make_shared<Holder<T>>(value);
return *this;
}
bool empty() const {
return !data;
}
const std::type_info& getTypeInfo() const {
return data ? data->getTypeInfo() : typeid(void);
}
template<typename T>
const T& cast() const {
if (data->getTypeInfo() != typeid(T)) {
throw std::bad_cast();
}
return static_cast<Holder<T>*>(data.get())->value;
}
private:
class BaseHolder {
public:
virtual ~BaseHolder() {}
virtual std::shared_ptr<BaseHolder> clone() const = 0;
virtual const std::type_info& getTypeInfo() const = 0;
};
template <typename T>
class Holder : public BaseHolder {
public:
Holder(const T& value) : value(value) {}
std::shared_ptr<BaseHolder> clone() const override {
return std::make_shared<Holder<T>>(value);
}
const std::type_info& getTypeInfo() const override {
return typeid(T);
}
T value;
};
std::shared_ptr<BaseHolder> data;
};
int main() {
Any a = 5;
Any b = std::string("Hello");
std::cout << a.cast<int>() << std::endl;
std::cout << b.cast<std::string>() << std::endl;
try {
std::cout << a.cast<std::string>() << std::endl;
} catch (const std::bad_cast& e) {
std::cout << "Failed to cast" << std::endl;
}
return 0;
}
此类使用了类型擦除的技巧,通过使用std::shared_ptr存储具体类型的对象,并使用基类指针访问,以在运行时保持类型信息。
Any类提供了以下功能:
- 默认构造函数
Any():创建一个空的Any对象。 - 模板构造函数
Any(const T& value):创建一个包含给定值的Any对象。 - 拷贝构造函数
Any(const Any& other):创建一个与另一个Any对象相同的副本。 - 拷贝赋值运算符
operator=(const Any& other):将一个Any对象的值赋给另一个对象。 - 模板赋值运算符
operator=(const T& value):将给定值赋给Any对象。 empty()函数:检查Any对象是否为空。getTypeInfo()函数:获取存储的对象的类型信息。- 模板函数
cast():将存储的对象转换为指定类型,并返回引用。如果存储的对象与指定类型不匹配,则抛出std::bad_cast异常。
在示例的main()函数中,我们创建了两个Any对象a和b,并分别存储了一个整数和一个字符串。然后,我们使用cast()函数将存储的对象转换为相应的类型,并输出结果。最后,我们尝试将一个对象转换为错误的类型,并在异常处理块中捕获异常。
请注意,此示例只是Any类的一个简单实现,可能并不完善。在实际使用中,可能需要考虑更多的细节和改进,例如异常安全性、内存管理等
原文地址: https://www.cveoy.top/t/topic/ifPG 著作权归作者所有。请勿转载和采集!