多态性和覆盖C ++中类模板的方法

Polymorphism and overriding a method from a class template in C++

本问题已经有最佳答案,请猛点这里访问。

我希望有一个具有我方法的基本实现的类模板,以及一组使用具有特定类型(double、int、char*)的模板类并根据需要重写这些基本实现的一些子集的子类。但是,除非将对象声明为子类的实例,否则似乎不会调用被重写的方法。在研究这个问题时,我想到了以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>

template <typename T>
class BaseClass {
public:
    virtual void print1 (T thing) {
        std::cout <<"Base print1:" << thing << std::endl;
    }

    virtual void print2 (T thing) {
        std::cout <<"Base print2:" << thing << std::endl;
    }
};

class IntClass : public BaseClass<int> {
public:
    void print2 (int thing) {
        std::cout <<"Int print2:" << thing << std::endl;
    }
};

int main()
{
    BaseClass<int> thing = IntClass();
    thing.print1(1);
    thing.print2(1);

    IntClass thing2 = IntClass();
    thing2.print1(2);
    thing2.print2(2);

    return 0;
}

我的预期产出是:

1
2
3
4
Base print1: 1
Int print2: 1
Base print1: 2
Int print2: 2

但相反,我得到:

1
2
3
4
Base print1: 1
Base print2: 1
Base print1: 2
Int print2: 2

是否有可能在这里实现我的目标,或者在这种情况下,我最好为每种类型创建单独的基类?抱歉,如果我的术语有点过时,我对C++是比较新的。


BaseClass thing = IntClass(); </P >

这不' t做什么你认为它不会。它创源A临时审院IntClass然后copies它的热情,这是thingBaseClass。。。。。。。的结果是被称为面向slicing(你可以搜索这)。 </P >

在这个案例中,作为衍生型是已知在编译时,没有理由不去使用IntClassthing型。但是,通用化,你需要使用指针。下面是一个实例: </P >

1
2
std::unique_ptr<BaseClass<int>> thing(new IntClass);
thing->print1(1);

该类型的thingBaseClass,不IntClass。。。。。。。《临时IntClass你用来initialise嘛的蜜蜂的焊缝,后copying的BaseClass子对象。copying部分面向一样,这是有时slicing为家。 </P >

当你polymorphism厂使用的证明人或分到一级基地,这可能推荐的一种衍生类的对象。你会得到预期的结果,与一个参考的IntClass面向: </P >

1
2
3
4
5
6
// In C++11 or later, you can bind an rvalue reference to a temporary, extending its lifetime
BaseClass<int> && thing = IntClass();

// If you're stuck in the past, you can bind an lvalue reference to a variable
IntClass ic;
BaseClass<int> & thing = ic;


如果你使用的是一个指针,你会达到你的预期的结果。但是,为短期研究这个答案有learned我们有发生什么,这里是‘东西’的对象被称为的事;不是参数,把中的一部分,这是intclass of基类和简单的discards的休息。这是被称为面向slicing。。。。。。。 </P >