【问题标题】:what's a c++ equivalent of a generic?什么是泛型的 C++ 等价物?
【发布时间】:2011-04-10 14:16:03
【问题描述】:

假设我正在实现一个多态树数据结构,它可以接收任何类型的数据......

Tree<Int> or Tree<String> or Tree<Object>

但我在 C++ 中实现它....如何指定树可以包含类似于 Java 中的泛型的任意类型

在 C++ 中是否也存在相当于 Java 的 Object 对象,其中 C++ 中的所有对象都继承 Object

【问题讨论】:

  • 据我所知,你不能在 java 中做到这一点。你所能做的就是创建一个Object 类型的树。您将需要更大程度的动态类型来实现您所描述的内容。听起来您想要“编写一次,然后为任意类型生成树。”。每棵树本身还是单态的,只能包含Strings,或者Ints等。
  • 除了 Tree 之外,您实际上可以在 java 中做到这一点。 int 是原始类型,他应该使用 Tree.

标签: java c++ generics object polymorphism


【解决方案1】:

最接近 Java 泛型的等价物是 C++ 中的模板。如果严格来说,它并不等同。但这就是你在 C++ 中所拥有的。因此,为了满足您的需要,您需要做一些工作,以便可以用 C++ 编写等效代码。

这里有一些比较 C++ 模板和 Java 泛型的文章的链接:

【讨论】:

    【解决方案2】:

    如果您的目标是拥有一个可以包含任何内容的容器,您可以将容器的值类型设置为Boost Any。但听起来您正在寻找的是同质容器,而此处的模板答案对此很有意义。

    【讨论】:

      【解决方案3】:

      在 C++ 中,您使用模板,格式为

      template <typename T>
          class Tree {
              TreeNode<T> Root
              ...
          };
      

      模板与泛型不同,它们提供了更多的灵活性(并且更有能力让自己陷入困境)。例如,您不能将模板类型参数限制为某种类型的子类。而且 C++ 在模板内部没有强类型检查,这很容易造成混乱。

      【讨论】:

      • “更灵活一点”是一种轻描淡写的说法。模板构成图灵完备的元语言。
      【解决方案4】:

      您正在寻找的是 C++ templates

      你可以像这样声明一个模板类:

      template<class TType>
      class AClass
      {
      private:
          TType *somePointer;
      };
      

      类不像 C# 和 Java 等语言那样源自 C++ 中的公共基础。您将获得的最接近的是void*,但这会将所有类型安全都抛在脑后,我不会推荐它。

      【讨论】:

        【解决方案5】:

        您正在使用泛型语言:Tree&lt;Int&gt;Tree&lt;String&gt; 不应该包含任何类型的对象;它们专门保存整数或字符串。只有Tree&lt;Object&gt; 能够保存“任何”类型,但C++ 没有与“对象”等价的概念。尽管我自己没有使用过,但您也许可以使用 Boost.Any 在树中保存“任何”类型。

        使用 C++ 模板来保存特定类型:

        template<typename T>
        class Tree {
            ...
        };
        

        用法:

        Tree<int> treeOfInts;
        

        【讨论】:

          【解决方案6】:

          【讨论】:

          • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
          • 很奇怪。如果你在 Synergy(和 Feng?),那么我们可能都在 KWII 工作过。
          【解决方案7】:

          好的,对 java 泛型的天真尝试将是 Tree&lt;void*&gt;。这不是很好,很多人会用以下内容替换它:

          class TreeBase { };
          class TreeInt : public TreeBase { int i; };
          

          然后使用Tree&lt;TreeBase*&gt;。这使您可以指定哪些类型将与它兼容。它相当于 java 的 Object 东西。

          另一层是Tree&lt;Node&gt; 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);
            }
          

          这种方法的优点是每个树节点都可以有不同的行为。缺点是它有点冗长。

          【讨论】:

            猜你喜欢
            • 2010-10-06
            • 1970-01-01
            • 2014-05-08
            • 2018-01-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-19
            • 2010-12-07
            相关资源
            最近更新 更多