2012-09-12 48 views
1

专门研究一个池类我有一个模板化的池类来管理一堆对象的生命周期。通常,它会根据需要调用new和delete,但我也可以传递一个create函数并销毁函数。根据创建函数是否通过

现在,对于这个类的一些用户,我希望有一个私有构造函数,并且只允许传递一个create/destroy函数。这会导致编译错误,因为即使未使用“新T”行仍在池类中。到目前为止,我已经通过让游泳池成为有问题的课程的朋友来解决这个问题。这仍然会造成误用的可能性(例如,通过手动创建特定对象的池并且不传递创建/销毁函数),所以我想知道什么是专门化池类的最佳方法,以便我可以拥有真正的私有不使用朋友的模板参数上的构造函数。

回答

0

需要你可以专注你的模板:

template <typename T, bool Constructible> 
struct Pool 
{ 
    T * make() 
    { 
     return maker(std::common_type<Constructible>()); 
    } 

    T * maker(std::common_type<false>) { return T::create(); } 

    T * maker(std::common_type<true>) { return new T(); } 
}; 

Pool<Foo, true> fooPool; // uses "new Foo();" 
Pool<Bar, false> barPool; // uses "Bar::create();" 
1

如果我正确理解你的意图,我想我会做这样的事情:如果用户通过构造函数对象

template <class T> 
struct constructor { 
    T *make() { return new T; } 
    void destroy(T const *t) { delete t; } 
}; 

template <class T, class ctor = constructor<T> > 
class Pool { 
    ctor c; 
    // ... 
    T *t = c.make(): 

    // ... 

    c.destroy(t); 
}; 

,你的代码使用它的make/destroy函数。如果他们没有通过,则将使用constructor模板,其将使用newdelete

作为一个小的变化,你可能更喜欢让makedestroystatic成员函数,所以Pool内,你只需要使用ctor::make();ctor::destroy(t);

0

我相信这是最灵活的解决方案。这是基于特征 - 就像其他答案一样,但它使用起来非常简单。如果您需要更改建筑或销毁,请放置专门的功能。

我的建议:

template <typename T> 
T* std_new() { return new T(); } 
template <typename T> 
void std_delete(T* p) { delete p; } 

template <typename T, T*(*Create_)() = std_new<T>, void(*Destroy_)(T*) = std_delete<T> > 
class Pool { 
public: 
    T* create() { return Create_(); } 
    void destroy(T* p) { Destroy_(p); } 
}; 

及其用法:

Pool<int> pi; 
int* new_int_7() { return new int(7); } 
Pool<int, new_int_7> pi7; 

要保持阵列在池:

template <typename T, int N> 
T* std_new_arr() { return new T[N](); } 
template <typename T> 
void std_delete_arr(T* p) { delete [] p; } 

Pool<int, std_new_arr<int, 6>, std_delete_arr<int> > piarr; 

如果使用一些标准集装箱但是考虑与专门的allocato r(如果需要)可能是最佳选择。