使用静态方法(又名工厂)派生类,使用Base类进行模板化

时间:2012-01-27 13:12:39

标签: c++ templates

我想创建一些类,它们将具有私有/受保护的构造函数,并且将具有名为create()的静态方法。 我来告诉你代码:

template <class T>
struct ServicePtr
{
    std::shared_ptr<T> service;
};

template <class T>
struct ServicePtrDeleter
{
    void operator()(T* ref) const
    {
        if (ref->service.get())
        {
        }

        delete ref;
    }
};

template <typename T>
struct ServiceCreator
{
    static std::shared_ptr< ServicePtr<T> > create()
    {
        std::shared_ptr< ServicePtr<T> > servicePtr(new ServicePtr<T>);
        servicePtr->service.reset(new T);
        return servicePtr;
    }
};

class S:public IService,
public ServiceCreator<S>
{
    protected:
    S()
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }

    public:
    virtual ~S()
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

int main()
{
    auto s=S::create();
    return 0;
}

使用GCC 4.6.1进行编译时,出现以下错误:

  

main.cc:在静态成员函数'static std :: shared_ptr&gt;中ServiceCreator :: create()[with T = S]':
  main.cc:310:12:从这里实例化   main.cc:275:3:错误:'S :: S()'受保护
  main.cc:177:3:错误:在此上下文中   make: * [main.o]错误1

2 个答案:

答案 0 :(得分:1)

ServiceCreator::create()中,您可以这样做:

servicePtr->service.reset(new T);

如果TS,则会尝试创建S,但会失败,因为S具有受保护的构造函数。要允许不相关的类访问该构造函数,同时保持其受保护,您必须使创建者类(或只需要访问的成员函数)成为朋友:

friend ServiceCreator<S>::create;

答案 1 :(得分:0)

主要问题是ServiceCreator<T>::create()将尝试在此处实例化S:

static std::shared_ptr< ServicePtr<T> > create()
{
    // ...
    servicePtr->service.reset(new T); // T = class S
    return servicePtr;
}

但当然不能这样做,因为class S的构造函数受到保护!解决这个问题的一个简单方法就是让ServiceCreator成为S的朋友:

class S : public IService, public ServiceCreator<S>
{
  friend class ServiceCreator<S>;
  // ...
};