3
class A {
public:
    template<typename T> void func(size_t n, T values[]) { ... }
};

class B : public A {
public:
    void func(size_t n, uint32_t values[]) { ... }
};

为什么调用这段代码时函数B::func() 优先于函数模板?A::func()

uint32_t values[5];
A* obj = new B();
obj->func(5, values);
4

4 回答 4

6

两个原因——

  1. 在 C++ 中,仅当基类函数标记为虚拟时,成员函数才会覆盖基类成员函数。否则,C++ 将两者视为巧合同名的独立函数。这与 Java 形成对比,Java 中的函数以原子方式覆盖基类函数。

  2. 在 C++ 中,模板成员函数不能被标记为虚拟的。这部分是由于最常用的虚函数的实现 - vtables - 与 C++ 模板实例化系统相结合。C++ 将同一模板在不同类型参数上的所有实例化视为单独的函数,并延迟生成这些实例化。这是 vtable 实现的一个问题,因为 vtable 需要在编译时静态确定类中不同虚函数的数量,以及对它们的排序。由于模板虚函数意味着类中虚函数的数量和顺序未知,因此 C++ 不允许这样做。

于 2011-01-01T20:08:10.347 回答
1

如果您调用func类型的对象/指针/引用A,则会A::func被调用,因为func它不是虚拟的(而且它不能是:它是一个模板函数)。

你真的测试过你的代码吗?

于 2011-01-01T20:05:04.057 回答
0

A::func()未声明为virtual,因此编译器不会生成虚拟表和B::func()运行时调用所需的任何其他代码。它与模板无关。

于 2011-01-01T20:04:37.817 回答
0

因为 B::func 不是 A::func 的重载,而且无论你做什么都永远不可能。甚至不要尝试声明 A::func 虚拟,因为你不能。无论你想做什么,你都做不到。静态和动态多态性只是不混合在 C++ 中。

如果您的指针指向 B*,而不是 A*,您会期望调用它的版本。

于 2011-01-01T20:08:17.533 回答