使用模板和继承设计测试
Design test with templates and inheritance
我有一个关于c++设计的问题。正如您在下面的代码中看到的那样,存在一个设计问题。我希望能够有一个TestClass
,它继承自零或多个从ModeBase
派生的类(ModeOne
和ModeTwo
在这个例子中)。如果TestClass
继承自ModeOne
,它将有能力使用MethodeOne()
,这将是TestClass
实现MethodOne()
的要求,这是我想要的。
class ModeBase
{
//--Methods--------------------------------------------------------------------
public:
virtual ~ModeBase() = default;
};
class ModeOne : private ModeBase
{
//--Methods--------------------------------------------------------------------
public:
virtual ~ModeOne() = default;
virtual void MethodOne() {}
};
class ModeTwo : private ModeBase
{
//--Methods--------------------------------------------------------------------
public:
virtual ~ModeTwo() = default;
virtual void MethodTwo() {}
};
class TestBase
{
//--Methods--------------------------------------------------------------------
public:
TestBase() : currentMode_( nullptr ) {}
virtual ~TestBase() = default;
template <class Mode, class T>
void ChangeMode()
{
if( std::is_base_of<Mode, T>::value )
{
// Class does inherit from Mode so we make sure the current mode
// has changed
currentMode_ = std::make_shared<Mode>();
}
else
{
// Class does not inherit from Mode so we don't do anything
}
}
template <class Mode>
bool CurrentMode()
{
if( std::dynamic_pointer_cast<Mode>(currentMode_) != nullptr )
{
return true;
}
return false;
}
//--Data members---------------------------------------------------------------
private:
std::shared_ptr<ModeBase> currentMode_;
};
class TestOne
: public TestBase
, private ModeOne
, private ModeTwo
{
//--Methods--------------------------------------------------------------------
~TestOne() = default;
void HeartbeatTick()
{
if( CurrentMode<ModeOne>() )
{
MethodOne();
}
else if( CurrentMode<ModeTwo>() )
{
MethodTwo();
}
}
virtual void MethodOne() {}
virtual void MethodTwo() {}
};
class SomeManager
{
~SomeManager() = default;
void ChangeAllMode()
{
for( auto it = vector_.begin(); it != vector_.end(); ++it )
{
// Here is the problem with this implementation. I need to know
// the type of the TestBase derived class (TestOne) to use it as
// a `ChangeMode` method template parameter.
//(*it)->ChangeMode<AIModeFollowLine, SOMETYPE>();
}
};
std::vector<std::shared_ptr<TestBase>> vector_;
};
我已经知道这是糟糕的设计,因为vector_
将在运行时填充,所以我没有办法使用ChangeMode
这样。看来,这将是一个很好的解决方案,使用多种方法,不是吗?如果是这样,设计会是什么样子呢?
Multimethods(又名多重分派)处理基于所涉及的参数的运行时类型分派对单个函数的调用的问题。这似乎不是你的问题(或者我误解了你吗?),因为你有两个不同的方法名称,在两个不同的类型上实现。
您的目标似乎是基于您注入到类中的运行时类型来选择方法实现。目前还不清楚你是否能够决定注入的形式,但如果你是,那么你为什么不直接注入实现?然后可以使用隐式接口而不是显式接口。换句话说,为什么不注入一个类似functor
的对象?
class TestBase
{
public:
typedef std::function<void ()> Ticker;
TestBase(Ticker hbTicker) : ticker{hbTicker} {}
void HeartbeatTick() {
ticker();
}
void setTicker(Ticker hbTicker){
ticker = hbTicker;
}
private:
Ticker ticker;
};
如果符合你的要求,我觉得好像没那么复杂。
如果你真的需要实现多重调度,你可能需要在每个需要确定运行时类型的参数上实现visitor
模式。不确定这是否适用于多个参数(至少我自己没有尝试过多个参数)。或者您可以使用RTTI
和case语句或类似的东西
我真是太蠢了!我只需要使用不同的ChangeMode()
方法来了解TestBase
和TestOne
是否属于ModeBase
类型:
template<typename Mode>
bool
IsSame( TestBase* base )
{
return dynamic_cast<Mode*>(base) != nullptr;
};
template <class Mode>
void
ChangeMode()
{
if( isSame<Mode>(this) )
{
// Change the ticker method
}
else
{
}
}
相关文章:
- 继承函数的重载解析
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- 继承期间显示未知行为的子类
- 头文件-继承c++
- 尽管测试成功,CppUnit测试核心仍被丢弃.为什么
- 为什么在保护模式下继承升级不起作用
- 数据成员SFINAE的C++17测试:gcc vs clang
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 混合组合和继承的C++问题
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么二进制搜索在我的测试中不起作用
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 从父数组测试用例构造二叉树失败
- Boost单元测试夹具继承测试类,是否可以访问受保护的方法
- 为什么私有继承不能解决静态函数的歧义?(在 MSVC 中测试)
- 继承的模板类成员在链构造函数中测试良好,但此后"lost"
- C++继承测试
- 使用模板和继承设计测试