所以,我有这些课程,应该是低水平和快速。我不希望它们通常是虚拟的,而是希望函数是内联的。
在本例中,它们是互斥实现:
class MutexOne
{
public:
void lock () { /* implementation inline */ }
bool tryLock () { /* implementation inline */ }
void unlock () { /* implementation inline */ }
void reset () { /* implementation inline */ }
static const char* implementationName() { return "MutexOne"; }
};
class MutexTwo
{
public:
void lock () { /* implementation inline */ }
bool tryLock () { /* implementation inline */ }
void unlock () { /* implementation inline */ }
void reset () { /* implementation inline */ }
static const char* implementationName() { return "MutexTwo"; }
};
... etc ...所有的mmutexes都有相同的api。在测试框架内,我希望它们是虚拟的,这样我就可以执行如下操作:
testMutexImplementation( MutexVirtual& mutex )
{
mutex.lock(); // etc... do a lot of complex validating
}因此,在测试框架内,我希望我有一个干净的虚拟基类接口。但是在生产中,我不想为每个互斥操作支付一个虚拟函数,在一般情况下,其中许多操作类似于2-3个操作码。
因此,我想到了这样的方法,使用模板在事实之后添加一个虚拟表,只有当我需要它的时候。
因此,我首先创建所需的基类:
class MutexVirtual
{
public:
virtual void lock () = 0;
virtual bool tryLock () = 0;
virtual void unlock () = 0;
virtual void reset () = 0;
virtual const char* implementationName() = 0;
};然后使用模板魔术填充虚拟表:
template < typename T > class MutexPostVirtual : public MutexVirtual, public T
{
public:
void lock () { T::lock(); }
bool tryLock () { return T::tryLock(); }
void unlock () { T::unlock(); }
void reset () { T::reset(); }
const char* implementationName() { return T::implementationName(); }
};我很高兴,而且效果很好:
MutexPostVirtual<MutexOne> mutex1;
MutexPostVirtual<MutexTwo> mutex2;
testMutexImplementation( mutex1 );
testMutexImplementation( mutex2 );我不禁想,也许还有一种更干净、更简单的方法?如何才能更好地编写这些代码?
发布于 2017-04-27 22:30:29
我不知道用于测试的框架是什么,但是gtest有参数化试验,您可以用相同的测试来测试所有实现。
通过使用这个特性,您甚至不需要开始编写代码,在我的书中,这是最好的代码:您从未编写过的代码:)
https://codereview.stackexchange.com/questions/161984
复制相似问题