【发布时间】:2017-12-26 13:31:24
【问题描述】:
我正在查看 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;
}
我明白为什么它在 C++ 中不起作用。在 Java 中,解决方案是使用以下构造:
List<? extends Integer> intList = new ArrayList<>();
List<? extends Number> numList = intList; // OK. List<? extends Integer> is a subtype of List<? extends Number>
(假设 Integer 是 Number 的子类,如示例链接中所指出的那样)。
使用:
template <typename U>
void farmTest(const AnimalFarm<U *> &farm);
可能是解决方案,但有没有更好的方法在 C++ 中做到这一点,而不会失去 Cat 或 Dog 继承自 Animal 的事实(因为 Integer 是 Number 的子类型)?
谢谢。
【问题讨论】:
-
有时这类问题可以通过使用非模板
class AnimalFarmBase {};并从该基类template <typename T> class AnimalFarm : public AnimalFarmBase {};继承来解决。 -
AnimalFarm与Animal没有连接。您似乎想要的是一种定义模板化farmTest的方法,它只接受AnimalFram<T>,其中T是Animal类的子类。如果是这样,一种方法是将farmTest模板化,其中只有Ts 是Animal的子类。 -
在 C++ 中,你会用这个解决什么问题?我知道它在 Java 中解决的问题 - 但 IMO,C++ 中不存在这个问题。 很好,您可以使用任何可行的方法来实例化模板,而不管继承如何。唯一的问题是,如果使用了错误的类型,它往往会产生可怕的编译错误消息,但这会(在未来的某一天)通过所谓的概念来解决。
-
我没有具体的 C++ 问题需要解决。虽然我不是 Java 程序员,但问题来自 Java,然后我只是问自己,我将如何在 C++ 中做到这一点。
-
这种类型在 Java 中的主要目标是您可以为每个
AnimalFarm实现一个方法,而不管其类型参数如何,同时仍然确保该类型参数将是Animal的子类。在 C++ 中,这不是必需的:模板(在这个级别)是一些字符串替换引擎,并且“如果它工作,它工作 - 否则,它不工作”。 (这有很多缺点和限制,超出了本评论的范围)。正如 Christian 已经提到的:boost.org/doc/libs/1_60_0/libs/concept_check/concept_check.htm 的标准版本可能最终会有所帮助......
标签: java c++ templates inheritance