例如,我有一个包含的节点
Node * next;
[X] data;
我怎么能填写[X],这样我就可以生成A、B、C、D类型的"数据",我稍后会确定。我试图使其无效,但这只会导致错误。我使用它来创建一个包含一个变量的链表,该变量可以是a B C D类型。
您可以使用模板,也可以使用void指针(当模板可以起作用时,您不应该在C++中使用void指针)。
template <typename T>
struct Node {
Node * next;
T data;
};
现在Node<int>
和Node<float>
是不同的类型。您可以使用任何类型作为参数,只要该类型可以是默认构造的。如果您想将T
限制为一组类型中的一个,那么答案会涉及更多,但通常没有充分的理由这样做。
另一方面,如果您希望单个链表能够容纳许多不同的类型,则T
必须能够表示所有这些类型。例如,如果要存储的所有类型都派生自公共类A
,则可以使用Node<std::unique_ptr<A>>
,然后可以在该特定列表中存储A
或A
的任何其他派生子类型。
如果您希望一个列表能够容纳一组不相关类型中的任何一个的元素,则需要构建一个能够存储所有这些元素的"变体"结构,以及指示其当前包含的类型的某个字段,然后使用该变体结构作为Node
的类型参数。
如果您希望一个列表能够容纳任何类型的元素,那么除了为data
:Node<void *>
使用空指针之外,您没有太多选项。但这种技术有很多需要注意的地方,主要是决定谁拥有指向的分配,并找出删除它们的正确方法。
(请注意,尽管我写了Node * next
,但next
实际上是Node<T> *
。在Node
类中,模板参数是隐含的。)
C++是强类型的,因此需要在编译时知道所有类型。
你可以考虑使用模板:
template<typename T>
void f(T s)
{
std::cout << s << 'n';
}
template void f<double>(double); // instantiates f<double>(double)
template void f<>(char); // instantiates f<char>(char), template argument deduced
template void f(int); // instantiates f<int>(int), template argument deduced
示例
或A、B、C&D都可以从一个类继承,然后可以将它们存储为父类。它的内容比我在一个小例子中所能轻易展示的要多得多,所以这里有一个有用的链接
基本上,作为一个概念示例,您可以有一个父类vehicle
,并有一个vehicle
s的列表。
然后,您将实际生成存储在列表中的几个car
s、motorbike
s和truck
s(它们都继承自vehicle
)(因为它们都是vehicle
s以及它们自己的子类。