PDA

View Full Version : templates / Q_OBJECT question



_borker_
19th December 2007, 19:09
Hi all, I have a bit of a question about the best / Qt way of handling the following:

I'm building a Qt library that performs queries against a web service, interprets the XML results and creates instances of classes representing the results.

for simplicity, lets say the XML looks like this:


<node A>
<attribute node A1 />
<attribute node A2 />
<attribute node A3 />
</node A>
<node B>
<attribute node B1 />
<attribute node B2 />
</node B>
... etc...


The idea is to turn a query phrased as an http request that returns xml containing one or more instances of a single node type into instances of their matching class.

So on the Qt/C++ side we have:

//the classes matching the possible response types (lets call em 'the node classes')
Class virtual base NodeClass //the common properties
Class ANodeClass //NodeClass subclass mapping <node A>
Class BNodeClass //NodeClass subclass mapping <node B>
Class ... etc..

Class WebService //holds some basic info about the web service
Class QueryManager //contains a list of queries, start executing them, monitors their progress
Class Query //forms an http request and receives XML which is stored in a buffer
Class XmlResultHandler //takes an XML buffer and creates an instance of one of the node classes

So, basically I'm trying to create a situation where a query is executed and behaves as a factory to produce instances of one or other of the node classes.

There are two main issues I'm struggling with...

1. My first thought was to make the Query class a template so it could be instantiated with one of the node classes as the template type, which it could then return an instance of. Because Query is a Q_OBJECT this can't be done. Is there another approach that could allow a single class to return a dynamically selected type? Can you use multiple inheritance with a Q_OBJECT class and a pure C++ template class?

2. The XmlResultHandler class also produces an instance of a node class. There are a few common attributes in the base class but the majority of attributes are unique to each node subclass. With the basic pattern of 'parse the xml, call the member function' is there a way to implement this generically so that the matching of node types and their matching member functions can be determined dynamically? The idea here is that in the future if new nodes are introduced into the XML schema the code could load NodeClasses as plugins and dynamically determine how to process the XML and instantiate instances of the new NodeClass


thanks for any help, ideas or advice anyone can offer

wysota
19th December 2007, 20:08
I admit I haven't read the whole post, but it looks like templates are not for you - you can't decide which class to create during runtime, the template argument has to be specified during compilation. But if you think templates are for you, then make some object that is not derived from QObject and make it a member of your class - QObjects can't be templates, but they can have a member pointer that is a base class of a template class.


class ... {
Base *x;
};

class Base{};
template .... class X : public Base {...};

marcel
19th December 2007, 20:27
I think you can avoid templates. Why not using only a factory class + an abstract(basically for preventing instantiating this meaningless class) node class + node implementations?
The factory class will return Node(abstract) objects which you could identify later by adding a getType pure virtual method which subclasses actually implement.

For example:


AbstractNode *node = NodeFactory.CreateNode...;
switch(node->type())
{
...
case AbstractNode::eTypeANode:
{
dynamic_cast<TypeANode*>(node)->SomeTypeANodeSpecializedMethod();
break;
}
...
}

_borker_
19th December 2007, 20:28
thanks for the reply :)

When the query is created the return type will be known so it's possible to know the desired return type at compile time that will be what is used as the template class.

I'm mainly searching for a way to implement a behavior pattern that is more or less generic without having to create subclasses that don't do much more than just handle different return types.

I'll have a play around this evening with what you mentioned in your reply and see if that solves my problems

cheers
borker

jacek
19th December 2007, 20:30
What "return types" are we talking about here? Maybe QVariant is what you need?

_borker_
19th December 2007, 20:33
thanks Marcel, that looks like a good idea. From what you and wysota have said, steering clear of templates might well be the best idea here.

cheers
borker

_borker_
19th December 2007, 20:35
hmm, never really played around with QVariants, might be an option there also... thanks jacek :)