1

基本上从 C++ FAQ 我了解到:

虚函数允许派生类替换基类提供的实现。编译器确保只要有问题的对象实际上属于派生类,就总是调用替换,即使该对象是通过基指针而不是派生指针访问的。这允许在派生类中替换基类中的算法,即使用户不知道派生类。

但是,使用模板这变得不再正确。

我需要一个由另一个模板类派生的模板类。之后,我发现在基模板类中使用虚函数毫无意义,谷歌搜索后发现有一种技术可以克服泛型编程中的多态性限制,称为类型擦除。

我读过的示例和教程几乎与我的需求无关。另外我不确定我是否正确理解了类型擦除的概念。作为初学者,我只需要做:

template <typename T>
class Foo
{
public:
    virtual void doX(){cout<<"doX from Foo"<<endl;}
};

template <typename T>
class Bar : public Foo<T>
{
public:
    void doX(){cout<<"doX from Bar"<<endl;}
};

和,

Foo<int>* p;
Foo<int> i;
i.doX();           // "doX from Foo", it's ok
Bar<int> j;
j.doX();           // "doX from Bar", it's ok
p=&i;
p->doX();          // should be "doX from Foo", it's ok
p=&j;
p->doX();          // I expect "doX from Bar", but it's "doX from Foo"

编辑: 我的问题是如何实现上述行为?没有模板,它按预期工作。我需要同样的普通课程。

简单地说,我有一个基类B。这是一个模板类。它具有虚拟功能。而且我还有一个子类,B它也是一个模板类,它应该重新实现 B(以某种方式实现的虚函数B)的一些行为。

EDIT2:刚刚编辑了标题。 我正在使用标志使用 g++ 4.6.3 编译器编译我的代码,-std=c++0x因为我需要std::thread并且std::unique_ptr在我的代码中。令人惊讶的是,删除-std=c++0x上述代码按预期工作。我还尝试了 g++ 4.7,2011 和 2003 标准都没有问题。

4

2 回答 2

0

好吧,它不起作用,因为 p 被分配给 i 指针,而 i 是 Foo 的类型。您正在使用基类函数。您应该使基类函数纯虚拟(通过= 0在函数末尾添加)。然后它应该工作。

编辑:我没有注意到它被你检查为 OK,以为那是错误。我自己用 msvc 编译器尝试了代码,它确实按预期工作。

于 2012-07-04T18:16:08.567 回答
-1

因为函数 doX 不是虚拟的。在派生类中,您隐藏函数 doX,而不是重载,因此动态多态性不起作用。

编辑。
当您使用 -std=c++0x 标志时,GCC 4.6.3 在这种情况下存在错误。
编辑2。
可能 GCC 4.6.3 没有这样的错误,问题出在 TS 编译器上。

于 2012-07-04T18:03:27.470 回答