我有一个看起来像 Boost.Array 的简单类。有两个模板参数 T 和 N。Boost.Array 的一个缺点是,每个使用这种数组的方法都必须是一个带有参数 N 的模板(T 是可以的)。结果是整个程序往往是一个模板。一个想法是创建一个仅依赖于 T(类似于 ArrayInterface)的接口(仅具有纯虚函数的抽象类)。现在每个其他类只访问接口,因此只需要模板参数 T(与 N 相比,它或多或少总是已知的)。如果使用接口,这里的缺点是虚拟调用的开销(更多错失内联调用的机会)。直到这里只有事实。
template<typename T>
class ArrayInterface {
public:
virtual ~ArrayInterface() {};
virtual T Get(int i) = 0;
};
template<typename T, int N>
class Array : ArrayInterface<T> {
public:
T Get(int i) { ... }
};
template<typename T, int N>
class ArrayWithoutInterface {
public:
T Get() { ... }
};
但我真正的问题在于其他地方。当我使用接口扩展 Boost.Array 时,Boost.Array 的直接实例化会变慢(在一种情况下,因子 4,这很重要)。如果我删除接口,Boost.Array 和以前一样快。我了解,如果通过 ArrayInterface 调用方法存在开销,那没关系。但是我不明白如果只有一个只有纯虚拟方法的附加接口并且直接调用该类,为什么对方法的调用会变慢。
Array<int, 1000> a;
a.Get(0); // Slow
ArrayWithoutInterface<int, 1000> awi;
awi.Get(0); // Fast
GCC 4.4.3 和 Clang 1.1 表现出相同的行为。