Interfaces, multiple inheritance, and casting

I have a problem that my current knowledge of C++ keeps me from solving.

I have two template classes that inherit from two separate classes (both the same but one has an abstract method that the other doesn't and shouldn't have). The one is an "interface" with instance data (IPlotLinkedItem), the other is a base class for the classes I will inherit from (QGraphicsItem).

Here is one of those template classes (the other is identical in structure... it is only intermediary interface that is different.

1
2
3
4
5
6
7
8
9
10
11
12
13
template<class GraphicsItemClass>
class MapTile : public GraphicsItemClass, public IMapTile
{
	static_assert	(	std::is_base_of<QGraphicsPolygonItem, GraphicsItemClass>::value || 
						std::is_base_of<QGraphicsRectItem, GraphicsItemClass>::value, 
						"you must use a QGraphics Polygon or SquareItem");
protected:
	MapTile() : GraphicsItemClass(), IMapTile() 
	{ 
	}

	~MapTile() { }
};


I will need to give some specifics about the class structure at this point so here goes:

1) the interface necessary for grabbing data from the plot associated with the graphics item:
IMapTile : IPlotLinkedItem

2) The two classes that use this template for will use the following classes as the "GraphicsItemClass" in the template above:
QGraphicsPolgyonItem : QGraphicsItem
QGraphicsRectItem : QGraphicsItem


Now here is what I am trying to accomplish: all these "items" are essentially graphics elements that use Qt's Graphics view API. (Details aren't that important... but it will give you an idea of why this is all necessary). I am creating a program that is meant to display a map using multiple layers of data (all which come from the associated plot). For this reason I have a layer manager that controls what data is shown. This layer manager is composed of layers which have the following data organization (only relevant items are shown):

1
2
3
4
5
6
class DataLayer
{
private:
	static int mSize;
	QGraphicsItem* mItemCollection;
};


The reason I need to use the QGraphicsItem is because that is how the Layer manager interfaces with the objects. However, the method used to "initialize" all graphics items in the layer still needs to associate those items with the plot they are meant to represent. The problem is converting between the two class types. I need to convert each QGraphicsItem to an IPlotLinkedItem in order to link the plot associated with data it shows.

Basically I have class C which inherits both B and A indirectly (through at least one generation of separation). I need to convert B into an A at runtime in order to initialize the data but there is no direct relationship between the two.

Normally I might do this:

 
IPlotLinkedItem : QGraphicsItem


Unfortunately I don't see this as a possibility because the classes I use in the template are already derived from QGraphicsItem. As far as I know, I cannot inherit from a base class twice in c++ so that makes this solution unusable. Please correct me if I am in error. Otherwise I need another way to do this.

Last edited on
From what I can gather from your question, you are looking for virtual inheritance. That allows you to have an inheritance tree, where the same class appears twice.

See http://en.cppreference.com/w/cpp/language/derived_class#Virtual_base_classes

EDIT:
Alternatively, if I understood correctly you could cast back down to MapItem and then back up to IPlotLinkedItem, assuming that you know the object was a map item in the first place.
Last edited on
Ok. That info is good to know. However, it doesn't help in my case because I don't want duplicate instantiated classes either. Consider this:

Lets say I declare:
IPlotLinkedItem : virtual public QGraphicsItem {};

In the Qt specification:
QGraphicsPolygonItem : QAbstractGraphicsShapeItem which in turn : QGraphicsItem

Now... if I use:
HexTile : MapTile<QGraphicsPolygonItem> this means that HexTile will have the following inheritance structure:

HexTile : (MapTile template) : QGraphicsPolygonItem, IMapTile

Since IMapTile indirectly inherits a virtual QGraphicsItem and QGraphicsPolgygonItem indirectly inherits a a non-virtual QGraphicsItem, that means two QGraphicsItem will exist.

Your second suggestion complies. Thank you.
Last edited on
Topic archived. No new replies allowed.