开发者

what's a c++ equivalent of a generic?

开发者 https://www.devze.com 2023-02-23 03:29 出处:网络
suppose i\'m implementing a polymorphic tree data structure that can take on data of any type... Tree<Int> or Tree<String> or Tree<Object>

suppose i'm implementing a polymorphic tree data structure that can take on data of any type...

Tree<Int> or Tree<String> or Tree<Object>
开发者_如何学编程

but I'm implementing it in C++....how would I specify that the tree can contain an arbitrary type similar to generics in Java

also is there an equivalent of Java's Object object in C++ in which all objects in C++ inherits Object


The nearest equivalent of Java's generic is template in C++. Its not equivalent as such, if strictly speaking. But that is what you've in C++. So to suit your need, you've to work a little bit so that you can write equivalent code in C++.

Here're few links to some articles that compare C++ template with Java generics:

  • Java Generics and C++ Templates (at Dr Dobbs)
  • Generics in C#, Java, and C++ (at artima.com)


If your goal is to have a single container that can contain anything, you could make the container's value type be Boost Any. But it sounds like what you're looking for is a homogenous container, and the template answers here make sense for that.


In C++, you use templates, in the form

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

Templates aren't identical to generics, they offer a bit more flexibility (and more ability to shoot yourself in the foot). You can't constrain a template type parameter to be a subclass of a certain type for example. And C++ doesn't have strong type checking inside the template, which is where it can be easy to make a mess.


What you're looking for are C++ templates.

You can declare a templated class like:

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

Classes do not derive from a common base in C++, like they do in languages like C# and Java. The closest you'll get is a void*, but that throws all type-safety out the door and I wouldn't recommend it.


You are using the language of generics: Tree<Int> or Tree<String> aren't supposed to hold objects of any type; they specifically hold integers or strings. Only Tree<Object> would be able to hold "any" type, but C++ doesn't have a concept equivalent to "object". You might be able to hold "any" type in your tree using Boost.Any although I haven't used it myself.

Use C++ templates to hold a specific type:

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

Usage:

Tree<int> treeOfInts;


Templates.

http://www.cplusplus.com/doc/tutorial/templates/


Ok, naive attempt at java's generics would be Tree<void*>. That's not very good and many people will replace that with the following:

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

And then use Tree<TreeBase*>. This lets you specify which types will be compatible with it. It's equivalent of the java's Object thing.

Yet another layer would be to have Tree<Node> n; with just simple struct Node { TreeBase *b; };

But since we're talking about trees, c++ has considerably better way to do that, since it's directly supported via the c++ classes:

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;
};

Creating the tree couldnt be easier, once necessary types are available:

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);
  }

This approach has the advantage that every treenode can have different behaviour. The downside is that it's slightly verbose.

0

精彩评论

暂无评论...
验证码 换一张
取 消