Sca*_*cab 5 c++ java inheritance templates
我正在查看这个https://docs.oracle.com/javase/tutorial/java/generics/subtyping.html和https://docs.oracle.com/javase/tutorial/java/generics/inheritance.html并询问我自己如何在C++中实现它.
我有这个小例子来说明:
#include <iostream>
class Animal
{
public:
virtual std::string type() const = 0;
virtual ~Animal() {}
};
class Dog : public Animal
{
public:
virtual std::string type() const {
return "I am a dog";
}
};
class Cat : public Animal
{
public:
virtual std::string type() const {
return "I am a cat";
}
};
template <typename T>
class AnimalFarm
{
};
void farmTest(const AnimalFarm<Animal *> &farm)
{
std::cout << "test farm";
}
int main(int argc, char *argv[])
{
AnimalFarm<Dog *> dogFarm;
AnimalFarm<Animal *> animalFarm;
farmTest(animalFarm); // OK
farmTest(dogFarm); // NOK compiler error as class AnimalFarm<Dog *> does not inherits from class AnimalFarm<Animal *>
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我理解为什么它在C++中不起作用.在Java中,解决方案是使用以下构造:
List<? extends Integer> intList = new ArrayList<>();
List<? extends Number> numList = intList; // OK. List<? extends Integer> is a subtype of List<? extends Number>
Run Code Online (Sandbox Code Playgroud)
(给定它Integer是Number示例链接中指出的子类).
使用:
template <typename U>
void farmTest(const AnimalFarm<U *> &farm);
Run Code Online (Sandbox Code Playgroud)
可能是解决方案,但有没有更好的方法在C++中做到这一点而不会失去Cat或Dog从Animal继承的事实(作为Integer一个子类型Number)?
谢谢.
如果你的最终游戏是在和之间形成一个is-a关系,那么一些具有类型特征的模板专业化可以做到这一点.AnimalFarm<Dog *>AnimalFarm<Animal *>
template <typename T, typename = void>
class AnimalFarm // Primary template
{
};
template<typename T>
class AnimalFarm<T*,
std::enable_if_t<
!std::is_same<T, Animal>::value &&
std::is_base_of<Animal, T>::value
>
> // Specialization only instantiated when both conditions hold
// Otherwise SFINAE
: public AnimalFarm<Animal*>
{
};
Run Code Online (Sandbox Code Playgroud)
由于AnimalFarm<Animal*>成为公共基础AnimalFarm<Dog*>,函数参数引用将绑定到它.虽然您应该注意到相应的层次结构是平的,无论它有多深Animal.
你可以看看live.
| 归档时间: |
|
| 查看次数: |
299 次 |
| 最近记录: |