class Base
{
public:
virtual ~Base() {}
virtual void Foo() = 0;
};
class FirstDerived: public Base
{
public:
void Foo() { cout << "FirstDerived" << endl; }
};
class SecondDerived: public Base
{
public:
void Foo() { cout << "SecondDerived" << endl; }
};
union PreallocatedStorage
{
PreallocatedStorage() {}
~PreallocatedStorage() {}
FirstDerived First;
SecondDerived Second;
};
class ContainingObject
{
public:
Base* GetObject()
{
if (!m_ptr)
{
// TODO: Make runtime decision on which implementation to instantiate.
m_ptr = new(&m_storage) SecondDerived();
}
return m_ptr;
}
~ContainingObject()
{
if (m_ptr)
{
m_ptr->~Base();
}
}
private:
PreallocatedStorage m_storage;
Base* m_ptr = nullptr;
};
int main()
{
auto object = make_unique<ContainingObject>();
// ...
// Later, at a point where I don't want to make more heap allocations...
// ...
auto baseObject = object->GetObject();
baseObject->Foo();
return 0;
}
What I'm trying to achieve here:
- I need to instantiate a class that has virtual methods.
- At the point in time I know exactly which derived class to instantiate, I cannot make further heap allocations (this is just out of curiosity, so the exact reason why is not relevant).
- Hence, I want to somehow pre-allocate enough space to hold any possible implementation, and then decide later what class I'm going to instantiate in it.
Is there anything standards-non-compliant/undefined behavior in the above code?