为什么这种类型的擦除实现(简化的 boost:any)会出现分段错误

Why does this type erasure implementation (simplified boost:any) gives segmentation fault?

本文关键字:any 分段 boost 错误 类型 种类 擦除 实现 为什么      更新时间:2023-10-16

我正在尝试自己实现任意类型的通用容器(类似于boost:any),只是为了了解这个习语,我试图理解为什么我的代码给出了分段错误。

class IValue
{
public:
    IValue() = default;
    virtual ~IValue() = default;
};
template<typename T>
class Value : public IValue
{
public:
    Value(T value) : val(value){}
    virtual ~Value() override
    {
    }
    T get()
    {
        return val;
    }
private:
    T val;
};
class any
{
public:
    template<typename U>
    any(U element)
    {
        elem = new Value<U>(element);
    }
    ~any()
    {
        delete elem;
    }
    IValue* get_type_erased_value()
    {
        return elem;
    }

private:
    IValue* elem;
};
template<typename T>
T any_cast(any a)
{
    Value<T>* stored_element = dynamic_cast<Value<T>*>(a.get_type_erased_value());
    if(stored_element)
    {
        return stored_element->get();
    }
    else
    {
        cout << "Any cast failed. Could not cast down to required typen";
        return T();
    }
}
struct foo
{
    int a;
    float b;
    char c;
};
ostream& operator<<(ostream& stream, foo& a)
{
    stream << '{' << a.a << ',' << a.b << ',' << a.c << '}' << 'n';
    return stream;
}
int main()
{
    any a = string("Any string value");
    any b = int(17);
    any c = foo({27,3.5,'g'});
    string s = any_cast<string>(a);
    int i = any_cast<int>(b);
    foo f = any_cast<foo>(c);
    cout << "Any string contained: " << s << 'n';
    cout << "Any int contained: " << i << 'n';
    cout << "Any struct foo contained: " << f << 'n';
    return 0;
}

输出是我想要的,转换似乎工作正常,但程序总是在最后崩溃。析构函数未正确调用或指针的释放一定有问题。有人可以给我一个提示吗?

谢谢

any类型的隐式定义复制构造函数仅复制IValue指针,因此原始对象和副本都将删除相同的指针。您需要编写一个实际复制存储对象的复制构造函数。