Search code examples
c++pointersshared-ptrfactory

Factory function which returns object of specific type - how to do it in better way


I have 3 classes B, C, D, that derive from one base class A:

class A
{
// body
};

class B : public A
{
// body
};

class C : public A
{
// body
};

class D : public A
{
// body
};

I want to create a factory function that will let me create object of specific type (B, C or D) and return it as a pointer to A class:

typedef std::shared_ptr<A> a_ptr;

a_ptr createObject(int type)
{
    switch(type)
    {
    case 0:
        return a_ptr(new B());
    break;
    case 1:
        return a_ptr(new C());
    break;
    case 2:
        return a_ptr(new D());
    break;
    }
}

And then if I have for example a pointer of type B, I'd like to assign B object created by a factory to it. The only reasonable solution for that that came to my mind would be:

std::shared_ptr<B> b = std::shared_ptr<B>(dynamic_cast<B*>(createObject(0)));

But it looks ugly. Is there any better solution for that? Or maybe I should try different way of creating objects with my function?


Solution

  • If you want to perform a run-time downcast of a shared_ptr, rather use std::dynamic_pointer_cast<>:

    std::shared_ptr<B> b = std::dynamic_pointer_cast<B>(createObject(0));
    

    If the type of the object to be created is determined at run-time, and yours is an attempt to check whether the returned object has type B, then I do not see better alternatives than a dynamic downcast.

    On the other hand, if you know with 100% certainty the pointed object has type B, then you could use std::static_pointer_cast<>:

    std::shared_ptr<B> b = std::static_pointer_cast<B>(createObject(0));
    

    In the moment you know this with 100% certainty, however, I do not see why such an instruction should not become:

    std::shared_ptr<B> b = std::make_shared<B>();