factory of templated class

2019-08-05 20:38发布

问题:

I'm not sure how to accomplish this in c++, but I want to prevent users of my library from providing singleton objects when I request a certain kind of object from their plugin that leverages my core libraries. I've tried a bunch of variations, but this is my current attempt at an implementation at a templated factory in C++.

Questions are embedded as comments in FooProvider.h stub. Thanks!

/*
 * IFooProvider.h
 */
//Interface - Factory for different variations of IFoo
class IFooProvider
{
    virtual std::shared_ptr<IFoo> getProvidedFoo();
}

//===========================================================================

/*
 * FooProvider.h
 */
template <typename T> //Not sure how to enforce that T is derived from IFoo?
class FooProvider : public IFooProvider
{
    std::shared_ptr<IFoo> getProvidedFoo()
    {
        //This doesn't work.
        //Not sure how to perform this cast or if this is even possible?
        std::shared_ptr<IFoo> rtn = std::make_shared<T>();
        return rtn;
    }
}

//===========================================================================

//Other team's implementation version.  Exists in a different library that I have no control over.

/*
 * MyFooProvider.h
 */
class MyFooProvider : public FooProvider<MyFoo>
{
    //Nothing really going on here.  Just want to implement a provider for MyFoo
}

//===========================================================================

回答1:

If you want compile time catching:

template <typename T>
class FooProvider : public IFooProvider
{
    std::shared_ptr<IFoo> getProvidedFoo()
    {
        std::shared_ptr<T> rtn = std::make_shared<T>();
        return rtn;
    }
}

No casting needed, and if T doesn't extend IFoo you'll get a compile time error saying that it couldn't convert 'rtn' from std::shared_ptr to std::shared_ptr - a pretty obvious error message.



回答2:

Hope this helps:

template <typename T> 
class FooProvider : public IFooProvider
{
    static_assert( std::is_convertible< T*, IFoo* >::value,
                   "Interface needs to be of type IFoo" );

    std::shared_ptr<IFoo> getProvidedFoo()
    {
        std::shared_ptr<IFoo> rtn = 
             static_pointer_cast<IFoo> ( std::make_shared<T>() );
        return rtn;
    }
}