what's a c++ equivalent of a generic?
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.
精彩评论