我们有时候需要把一个模板函数实现为虚函数,但是C++不支持模板虚函数(至少目前是),所以需要一些方法绕过去。以下是郁白师兄提供的解决方案,确实比较巧妙,之前没想过NVI(NonVirtual Interface)能解决这个问题。
class IAllocator
{
public:
virtual ~IAllocator() {};
virtual void *alloc(const int64_t size) = 0;
};
template <class T>
class TAllocator : public IAllocator
{
public:
TAllocator(T &allocator) : allocator_(allocator) {};
void *alloc(const int64_t size) {return allocator_.alloc(size);};
private:
T &allocator_;
};
class Base
{
public:
virtual ~Base() {};
public:
template <class Allocator>
void get_number(Allocator &allocator)
{
TAllocator<Allocator> ta(allocator);
this->get_number_(ta);
};
private:
virtual void get_number_(IAllocator &allocator) = 0;
};
class Sub1 : public Base
{
private:
void get_number_(IAllocator &allocator)
{
allocator.alloc(1);
fprintf(stdout, "sub1::get_number_ invoked\n");
};
};
class Sub2 : public Base
{
private:
void get_number_(IAllocator &allocator)
{
allocator.alloc(1);
fprintf(stdout, "sub2::get_number_ invoked\n");
};
};
class PA
{
public:
void *alloc(const int64_t sz)
{
fprintf(stdout, "pa::alloc sz=%ld\n", sz);
return NULL;
};
};
int main()
{
Sub1 s1;
Sub2 s2;
PA pa;
s1.get_number(pa);
s2.get_number(pa);
}
主要思想是把模板特化,特化之后的函数实现虚函数,把模板遵循的规则转化到继承体系,让一个实例化的模板参数遵循Interface的接口要求。所以TAllocator这个Wrapper至关重要。
参考文献:
[1] 【C++程序设计技巧】NVI(Non-Virtual Interface ), http://www.cnblogs.com/gnuhpc/archive/2012/01/17/2324836.html
[2] 纯虚函数能为private吗?, http://www.cppblog.com/zhuweisky/archive/2005/09/14/269.html
PREVIOUSgithub/gitcafe pages域名设置
NEXT测试一张静物