Solved List: Pointers to different data type (objects)
-
Hi All, I am new to Qt, I am stuck with a problem/architecture for a while and I am hoping for some direction here.
Problem: I am trying to make a CAD using qt. I have a list of geometries (cone, cylinder etc) and their corresponding geometry forms (.ui files). I want to make a container class which has a list (QVector/QList..). When I add/delete a geometry object (like cone, cylinder etc), I want the list to be updated. However, I am stuck because I cannot figure out how to make a list (Qlist or QVectors) with different data types (cone, cylinder etc). I tried making a subclass of these geometry objects from a main class (called geometry) and the other geometries inherit from this. But I cannot access the subclass methods from this list (as the container points to the base class and its members). The C++ community talks about type_cast, but it seems very complicated. Am I missing something obvious and easy to do in Qt? I am not sure if I need to upload any code, but I am mostly stuck in architecture rather than any coding issues. -
@rbharadw
A bit lost as to what you tried. You want aclass Shape
from whichclass Cone
,class Cylinder
etc. derive. Then you will have lists etc. ofShape
. The instances of the objects can beCone
,Cylinder
, or anything derived fromShape
.Show a code snippet of what you tried if you got stuck on this?
But I cannot access the subclass methods from this list
You can access common/virtual methods from
Shape
. If you need to access aCone
-specific method, you will need to know if a given object in the list is aCone
or not. If you make yourShape
derive fromQObject
you will be able to useqobject_cast<>()
(https://doc.qt.io/qt-5/qobject.html#qobject_cast, https://forum.qt.io/topic/59498/qobject_cast-vs-dynamic_cast) to find out and use if so. This is perhaps what you were looking for? -
Hi Jon, You understood the problem perfectly. I have added code here as well. What I need is a container list with Shapes, where I can then individually have access to each geometry object (like cone, here I call it myCone). My intent is also make a myConeForm and then somehow connect the glwidget to all these (sorry just giving you a bigger picture).
{ public: Shape(QString compName, int compType); public: QString componentName; int componentType;//Cone 0, Cylinder 2 const Shape *constData() const { return *compGeomList.constData(); } QVector<Shape *> shapeGeomList; }; //Header for Cone #include "Shape.h" #include "Cone.h" #include "ConeGeometry.h" class Cone : public Component { public: Cone(); ConeGeometry *myCone; }; //.cpp file for cone #include "Cone.h" Cone::Cone():Shape("Cone",0,0) { myCone = new ConeGeometry; } code_text
-
C++ basics: dynamic_cast<>
-
Ok. Thank you. I am able to see the list of shapes with the different objects now. But the examples are still not clear how to access the individual methods and variables of these objects. I wish Qt provided more generic examples rather than just push buttons.
-
@rbharadw Read my link, learn c++
-
Shape *shape = arrayOfShapes[index]; if (shape == nullptr) qDebug() << "nullptr"; Cone *cone = dynamic_cast<Cone *>(shape); if (cone == nullptr) qDebug() << "It's not a Cone"; else { qDebug() << "It is a Cone, so now I can go..."; cone->coneMethod(); }
-
Thank you Jon and Christian.
-
@JonB - The QObject class is quite handy. Is there a way I can use the indexOfClass or className() to recognize the subclass name (it can be cone or several other's..) in your loop? In other words, in your loop, where you define the Cone *cone = dynamic...., I would like to have a few lines to obtain the class name & then assign an object with this class name to do stuff. This will make it efficient because I might have a lot of such objects (not just cones or cylinders). Thanks for your reply as always.
-
For example this piece of code gives me an index of -1 even though the Cone class name is correct. ```
Shape *assem0 = new Shape("Assembly",0,0);Shape *Comp0 = new Cone; Cone *Cone1 = qobject_cast<Cone *>(Comp0); Shape *Comp1 = new Cylinder ; Cylinder *Cylinder1 = qobject_cast<rectConeComponent *>(Comp1);
assem0->compGeomList.append(Cone1);
assem0->compGeomList.append(Cylinder1);const char *name = assem0->constData()->metaObject()->className();
int index = assem0->constData()->metaObject()->indexOfClassInfo(name);(note that the Shape class has a QVector<Shape> *compGeomList)
-
@rbharadw
Even if you can get at the class names, I wouldn't be going down that route.I would like to have a few lines to obtain the class name & then assign an object with this class name to do stuff
This sounds fishy, whatever you might mean by it,.
C++ is a typed language. Dynamic/QObject casting is the better way to go.
i would wonder: why do you have a collection of these shapes and what you want to do is call subclass-specific methods on them? Is there a case for inherited methods from the base class, or intermediate classes for groups of common shapes which offer common methods? C++ also has template classes which could help, but still it's about finding common functionality.
-
@JonB What I meant was if there was a better than a check using a statement like this:
const char *name = assem0->constData()->metaObject()->className();
if (strcmp(name, "Cone")) qDebug() << "Name found, declare your cone class and do stuff";Your question is very appropriate. I thought about templates, but the thing is that although the data type (like vertices etc) is same for these shapes there are some analysis that are different for each. I am not sure as yet but perhaps I should give this more thought & see if can just override these methods in the subclasses. Thanks for all the pointers, appreciate it.
-
@rbharadw said in List: Pointers to different data type (objects):
For example this piece of code gives me an index of -1 even though the Cone class name is correct. ```
Shape *assem0 = new Shape("Assembly",0,0);
Cone *Cone1 = qobject_cast<Cone *>(Comp0);When you use qobject_cast<> then you should read what's needed to make it work:
"... and be declared with the Q_OBJECT macro."Make sure to know about he stuff you're using instead simply put something together and hope that it works somehow.
-
@Christian-Ehrlicher said in List: Pointers to different data type (objects):
Q_OBJEC
I already did this Christian. I appreciate you adhere to being a bit more polite in your replies rather than getting frustrated or replying as if the guy asking a question has no sense. I have been polite to you so far, but your tone of answers are not appreciated. If you cannot indulge in a professional and polite discussion, please abstain from giving replies. Please check other replies from Jon B, for example, very constructive and kind.