C ++:正确覆盖模板类中的虚函数

时间:2014-01-16 21:48:24

标签: c++ templates pointers reference virtual

请考虑以下代码:

template<typename T>
struct MyTempl
{
    virtual void doStuff(const T &value) = 0;
};

struct MyImpl : MyTempl<int>
{
    void doStuff(const int &value) {}
};

struct MyPtrImpl : MyTempl<int*>
{
    void doStuff(const int* &value) {}
};

MyImpl imp1;
MyPtrImpl imp2;

这将无法正确编译:编译器告诉我doStuff()中的MyPtrImpl是纯虚拟的,即。我未能正确覆盖它。但是,如果我将int*类型设置为int_ptr,并将其用作MyPtrImpl的模板参数,那么一切都会成功。

为什么编译器在没有typedef的情况下无法扣除我的意图?

1 个答案:

答案 0 :(得分:17)

您没有指定虚函数的正确参数类型,因此您没有覆盖它。这导致了一个抽象类,因为虚函数是纯粹的。

指定const引用类型的参数时,如

void doStuff(const int & value) {}

它实际上是写

的替代方案
void doStuff(int const & value) {}

应该被认为是声明常量引用的“正常”方式。从右到左阅读时,这意味着“对常量int的引用”。将相同的模式应用于指针类型int*会导致

void doStuff(int* const & value) {}

which compiles fine。但是那个不能按照上面的顺序编写,因为这意味着不同的东西:从右到左阅读const int* &,你得到“对常量int的指针的引用”。

正如您所提到的,如果您使用typedef为指针类型int*添加别名,则可以编写与上述订单一起使用的替代方法:

typedef int *T;
void doStuff(const T & value) {}

which also compiles fine,因为T现在被视为单一文字类型,而不是从上面引入含糊之处。换句话说,如何阅读const T &的唯一选择是“对const T的引用,它本身就是指向int的指针”。直觉上理解它有点困难,但不可能的是将其理解为“指向常量int”的指针,因为这不会有单个 {{ 1}}在说明中。

如果你使用C ++ 11编译器来检测这样的问题,我建议使用关键字T(在某些情况下,这个问题不会导致编译错误,而是会出现意外情况行为;例如,如果虚函数纯>:

override