0

I have the generic class which can store a value and a type of the value encoded as a string.

#include <iostream>
#include <string>
#include <memory>
#include <cassert>

struct IValueHolder 
{
    virtual ~IValueHolder() = default;
    virtual const std::string& getType() = 0;
    virtual void setType(const std::string& t_type) = 0;
};

template<class T>
class ValueHolder : public IValueHolder
{
private:
    T m_value;
    std::string m_type;
public:

    ValueHolder(T t_value) : m_value(t_value){}
    
    virtual const std::string& getType() override
    {
        return m_type;
    }

    virtual void setType(const std::string& t_type) override
    {
        m_type= t_type;
    }

    const T& getValue() const
    {
        return m_value;
    }
};

std::unique_ptr<IValueHolder> build_int_property()
{
    auto p32{ std::make_unique<ValueHolder<int32_t>>(0) };
    p32->setType("int32");
    return std::move(p32);
}

int main()
{

    auto v32 = dynamic_cast<ValueHolder<int32_t>*>(build_int_property().get());

    assert(v32->getValue() == 0); // FAILS 
    assert(v32->getType() == "int32"); // FAILS

    return EXIT_SUCCESS;
}

And I have another utility function build_int_property which builds an integer property. But unfortunately, the tests fail. Can anyone explain what is going wrong here?

Indri
  • 41
  • 1
  • 6
  • 1
    The pointer you form (v32) is to a temporary expression that goes out of scope on the next lines. – Shaggi May 30 '21 at 10:50
  • 1
    The old *dangling pointer* problem. Just do `auto p32 = build_int_property();` so the smart pointer stays around until the end-of-scope, and then `auto v32 = dynamic_cast*>(p32.get());` – Eljay May 30 '21 at 11:21

0 Answers0