多类型数据类 c++

Multi Typed Data Class c++

本文关键字:c++ 数据 多类型      更新时间:2023-10-16

我的问题是:

我需要创建一个支持以下代码的类 A:

class B{
   //some composed type
}
A a;
a.setValue(1);
a.setValue(2.2);
a.setValue('c');
a.setValue(B());

问题是我需要 a 实例来保留设置的值,并且只有它。这意味着我需要单个变量来包含数据,或者指向数据,但 A 不知道该类型,将来可以添加更多类型(例如 B)。

重载不能解决这个问题,因为如果类型是 int 而不是 double,值将保留在哪里?模板不能解决这个问题,因为对a.setValue(...)的调用必须看起来与上面所说的完全一样,没有模板所需的"<"、">"字符。

我还尝试了隐式强制,方法是定义:

class MyObj{
   MyObj* theObj;
   MyObj(){}
   virtual ~MyObj() = 0;//with later empty implementation
   setValue(myObj* newVal){theObj = newVal;}
}
class MyInt:MyObj{
   myInt(){}
   myInt(int theInt){}//for implicit cast from int
}
a.setValue(1);

这失败了,因为编译器可以自动将 int 转换为 myInt,但 setValue 需要 myObj,因此即使强制可以工作,编译器也不会自动进行推导。

我该如何解决这个问题?

谢谢。

以下是

基于 ECS 设计模式可以执行的操作:

struct BaseType {
    virtual ~BaseType() {}
};
template <typename T>
struct SpecializedType : public BaseType{
    SpecializedType(const T& v) : val(v) {}
    ~SpecializedType() {}
    T val;
};
class A {
    std::vector<std::unique_ptr<BaseType>> values;
public:
    template <typename T> void add(const T& val)
    {
        values.push_back(std::make_unique<SpecializedType<T>>(val));
    }
    template <typename T> T get()
    {
        for (auto& base : values)
        {
            auto* ptr = dynamic_cast<SpecializedType<T>*>(base.get());
            if (ptr)
                return ptr->val;
            }
            throw std::exception("no value found");
        }
    }
};
int main(void)
{
    A a;
    a.add(1.0f);
    a.add<std::string>("toto"); // You can specify the type when adding
    std::cout << a.get<float>() << std::endl;
    std::cout << a.get<std::string>() << std::endl;
    std::cout << a.get<int>() << std::endl; // Throws an exception because no int has been added
}

优点:

  • 您可以添加所需的每种类型

  • C++11/14 内存管理

缺点:

  • 每种类型只能有 1 个值

  • dynamic_cast

显然,如果需要,您可以改进系统,即通过在值中添加标识符以避免dynamic_cast