【发布时间】:2021-09-16 06:57:14
【问题描述】:
我目前正在尝试让模板和继承与 GMock 很好地配合。我有一种感觉,我想做的是两种相反的意识形态,我应该只使用一个接口,但我想避免使用接口,因为可能会产生虚拟调用开销(也许我过早地优化了)
无论如何,这是我正在尝试做的一个示例
class ConcreteObj {
public:
// Called a lot and so don't want to hit possible virtual overhead
void performant_function();
};
class MockObj {
public:
MOCK_METHOD(void, performant_function, (), ());
};
class ITest {
public:
template<typename T>
void test_function(T& );
};
class ConcreteTest : public ITest {
public:
template<typename T>
void test_function(T& ) {};
template<>
void test_function<ConcreteObj>(ConcreteObj& obj) {
// Do something with concrete object
obj.performant_function();
}
template<>
void test_function<MockObj>(MockObj& obj) {
// Do something with mock object
}
}
然后我想做的事情是这样的
ConcreteTest concrete_test;
ITest* test = &concrete_test;
// In production
ConcreteObj concrete_obj;
test.test_function(concrete_obj);
// In test
MockObj mock_obj;
test.test_function(mock_obj);
然后它会通过ITest 接口调用ConcreteTest,但是如果没有对ConcreteTest 的某种强制转换,上述方法显然无法工作,因为您不能拥有虚拟模板函数。
如果有人对我如何执行以下操作有任何想法,我将不胜感激,尽管我可能会放弃使用纯虚拟接口并处理如果有IObj 接口可能会出现的 vtable 开销ConcreteObj 和 MockObj 继承自。
【问题讨论】:
-
在这里真正拥有蛋糕并吃掉它的最佳方法是将依赖于
ConcreteObj的代码模板化为该类型。 -
另外:“(也许我过早地优化了)”如果你甚至对此感到疑惑,那么答案几乎肯定是肯定的。
-
ConcreteTest concrete_test; ITest* test = &concrete_test;的目的是什么?你想考哪一门课? -
我想测试 ConcreteTest,同时能够在 MockObj 和 ConcreteObj 上没有接口的情况下注入 MockObj
-
我看不出
class ITest的意义。删除它,你已经可以做concrete_test.test_function(concrete_obj);/concrete_test.test_function(concrete_obj);。
标签: c++ templates inheritance googlemock