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

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

我正在尝试自己实现任意类型的通用容器(类似于 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 type\n";
        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 指针,因此原始对象和副本都将删除同一个指针。您需要编写一个实际复制存储对象的复制构造函数。