假设我正在实现一个可以处理任何类型数据的多态树数据结构......
Tree<Int> or Tree<String> or Tree<Object>
但是我在C ++中实现它....我如何指定树可以包含类似于Java中的泛型的任意类型
在C ++中也有相当于Java的Object对象,其中C ++中的所有对象都继承了Object
答案 0 :(得分:3)
最接近的Java泛型是C ++中的模板。如果严格来说,它不等同于此。但这就是你在C ++中的用武之地。因此,为了满足您的需要,您需要稍微工作一下,这样您就可以用C ++编写等效的代码。
这里有一些链接到一些比较C ++模板和Java泛型的文章:
答案 1 :(得分:3)
如果您的目标是拥有一个可以包含任何内容的容器,则可以使容器的值类型为Boost Any。但听起来你正在寻找的是一个同质的容器,这里的模板答案对此有意义。
答案 2 :(得分:1)
在C ++中,您使用
形式的模板template <typename T>
class Tree {
TreeNode<T> Root
...
};
模板与泛型不同,它们提供了更多的灵活性(并且更有能力射击自己的脚)。例如,您不能将模板类型参数约束为某种类型的子类。并且C ++在模板中没有强大的类型检查,这是很容易弄得一团糟的地方。
答案 3 :(得分:1)
您正在寻找的是C ++ templates。
您可以声明一个模板化的类,如:
template<class TType>
class AClass
{
private:
TType *somePointer;
};
类不是从C ++中的公共基础派生出来的,就像在C#和Java等语言中那样。你得到的最接近的是一个void*
,但这会把所有类型安全抛到门外,我不推荐它。
答案 4 :(得分:1)
您使用的是泛型语言:Tree<Int>
或Tree<String>
不应该包含任何类型的对象;他们特别持有整数或字符串。只有Tree<Object>
能够保存“任何”类型,但C ++没有相当于“对象”的概念。您可以使用Boost.Any在树中保留“任意”类型,尽管我自己没有使用它。
使用C ++模板保存特定类型:
template<typename T>
class Tree {
...
};
用法:
Tree<int> treeOfInts;
答案 5 :(得分:0)
答案 6 :(得分:0)
好的,对java的泛型的天真尝试将是Tree<void*>
。这不是很好,很多人会用以下内容取而代之:
class TreeBase { };
class TreeInt : public TreeBase { int i; };
然后使用Tree<TreeBase*>
。这使您可以指定与其兼容的类型。它相当于java的Object事物。
另一层将是Tree<Node> n;
只有简单的struct Node { TreeBase *b; };
但是既然我们在谈论树,那么c ++有更好的方法,因为它是通过c ++类直接支持的:
class TreeNode { virtual ~TreeNode() { } };
class MyIntTreeNode : public TreeNode {
public:
MyTreeNode(int i) : i(i) { }
int i;
};
class MyStringTreeNode : public TreeNode {
public:
MyStringTreeNode(string s) : s(s) { }
string s;
};
class MyArrayTreeNode : public TreeNode {
public:
MyArrayTreeNode(std::vector<TreeNode*> v) : v(v) { }
std::vector<TreeNode*> v;
};
一旦有必要的类型,创建树就不容易了:
int main() {
MyIntTreeNode n1(10);
MyStringTreeNode n2("abc");
std::vector<TreeNode*> v;
v.push_back(&n1);
v.push_back(&n2);
MyArrayTreeNode n3(v);
algo(n3);
}
这种方法的优点是每个treenode都可以有不同的行为。缺点是它略显冗长。