覆盖派生类中的模板基方法?

时间:2017-04-29 23:04:57

标签: c++ c++11 class-template

假设我有一个基类,如下所示:

template <typename T>
class Base {
    // implementation
    void do_something() { /* ... */ } ;
};

然后,我创建了一个Derived类,如下所示,并覆盖do_something()方法:

template <typename T>
class Derived : public Base<T> {
    // implementation
    void do_something() { /* ... */ } ;
};

我知道虚拟化在类模板中不起作用,我只是隐藏了方法的实现。但我确实想将一堆派生类和基类存储到一个向量中,(我不想使用类型擦除或多态),

我的问题是,鉴于基类的static_cast类给了Derived基类,有没有什么方法可以将它们存储为基类他们实现了do_something class?

4 个答案:

答案 0 :(得分:2)

  

但我确实想将一堆派生类和基类存储到一个向量中,(我不想使用类型擦除或多态),

这在C ++中已经不可能了。在C ++中,向量只能包含相同静态类型的对象。向量可以包含不同类型对象的唯一方法是它们的静态类型是否仍然相同,但它们具有不同的动态类型,但这是类型擦除/多态,您说您不想使用它。

我想也许你需要重新考虑你的要求,因为你的问题实质上是:我想要做一些事情,但我不想使用技术X,它被明确定义为在C ++中做某事的唯一方法!

答案 1 :(得分:1)

我这样做了,似乎工作正常:

#include <iostream>

template <typename T>
struct Base {
    virtual void do_something() { std::cout << "Base::do_something()\n"; }
};

template <typename T>
struct Derived : public Base<T> {
    virtual void do_something() { std::cout << "Derived::do_something()\n"; }
};

int main() {
    Base<int> b;
    Derived<int> d;
    Base<int> *p;
    p = &b;
    p->do_something();
    p = &d;
    p->do_something();
    return 0;
}

输出:

Base::do_something()
Derived::do_something()

答案 2 :(得分:1)

melpomene的答案(为BaseOfBase结构添加无模板基础结构Base<T>)的一点变化允许使用不同{{派生的classe的基础的公共向量。 1}}类型。

一个工作示例

T

答案 3 :(得分:0)

当我们说虚拟化在模板类中不起作用时,这并不意味着您不能在模板类中执行虚拟功能,也不意味着您不能使用其专门版本覆盖成员函数。

@melpomene总体上显示了重写的示例,我将在这里专门介绍:

#include <iostream>

template <typename T>
class Base {
    public:
        virtual T do_something(T in) { std::cout << "Base::do_something()\n"; return in; }
};


class Derived : public Base<int> {
    public:
        virtual int do_something(int in) { std::cout << "Derived::do_something()\n"; return in - 1; }
};

void main()
{
    Base<int> b;
    Derived d;
    Base<int> *p = &b;
    auto r1 = p->do_something(10);
    std::cout << r1 <<std::endl;
    p = &d;
    auto r2 = p->do_something(10);
    std::cout << r2 << std::endl;        
}

将输出

Base::do_something()                                                                                                        
10                                                                                                                          
Derived::do_something()                                                                                                     
9 

表明它完全可以按预期工作。

我们所说的是什么意思

虚拟化在类模板中不起作用

基本上意味着您无法在希望使用基类的情况下将派生类用作模板。

考虑上述类Base<T>Derived,如果我们有以下代码:

#include <memory>

template <typename T>
void Test(std::unique_ptr<Base<T>> in){ std::cout << "This will not work with derived"; }

void main()
{
    Base<int> b;
    Derived d; 

    auto ptr = std::unique_ptr<Derived>(&d);
    Test(ptr); // <-- Will fail to compile as an invalid argument
}

它会失败,因为尽管std::unique_ptr<Derived>本身是从std::unique_ptr<Base<T>>继承来的,Derived并没有继承自Base<T>