PDA

View Full Version : construction of classes within classes



mobucl
9th January 2011, 15:57
Hi, Im not sure if this is the right place to post this but im new to QT and C++ and i have a question regarding classes and their creation so i thought id try here!

So want to create a class containg values and then i want to create antoher class inside with more values for organisation. (in matlab which i have used before I would create a structure within a structure). I have this code:


class atom
{
public:
QString type;
};


class data
{
//int size;
public:
QString name; //string for standard name from CIF
// QList < QList <QList<float> > >xyz; //3d array for XYZ values from CIF
// data(int);
int size;
double aSide;
double bSide;
double cSide;
double alpha;
double beta;
double gamma;
double volume;

atom atom1;
atom atom2;

};

So now i get a class containing aSide, bSide etc and then two classes for two atoms each containing type. Ok however as the number of atoms can change each time the class data is instanced i need to dynamically assign the number of atom classes on creation.

e.g.

data data1(3) - where 3 is the number of atoms i need and would automatically create the instance data1 with 3 atom classes (i.e. atom1 atom2 and atom3...)

then data data2(5) would create 5 atom classes etc......

Can anyone explain how to do this please? oes it require the use of a constructor?

Thanks in advance,

Matt

high_flyer
9th January 2011, 16:40
however as the number of atoms can change each time the class data is instanced i need to dynamically assign the number of atom classes on creation.
In C this would be done with an array, in C++ it is better to use container classes.
See QVector, QList, QSet and probably others.
STL has also a large collection of containers, that differ in various ways.
You should read about it.

However, in your case, QList or QVector would probably be good enough.


QVector<atom *> m_vecAtoms;

mobucl
10th January 2011, 08:56
Hi High_flyer,

Thanks for your reply. Regarding container classes, i have used these previously, however my problem is that i want to organize my data within these classes with a name and i dont think i can do this with (for example) QList. Indeed i asked a question on this recently and i was told to use structures and classes! see:

http://www.qtcentre.org/threads/37068-Renaming-multidimensional-QLists?p=170556&highlight=#post170556

Maybe i was not so clear in my previous example:

so in the class data i will have different variables including container classes and then another custom class inside this which i can then manage:


class atom // nested class
{
public:
QString type;
QList hkl
Qlist IJK
};

class data // main class
{
public:
QString name; //string for standard name from CIF
QList < QList <QList<float> > >xyz; //3d array for XYZ values from CIF
int size;
double aSide;
double alpha;
double gamma; //etc
atom atom1; //occurence 1 of custom nested class
atom atom2;
};

So now i have 2 custom classes within the class data in which i can access the variables type, hkl and IJK my name using data.atom1.type for example. If i use a container class directly (as far as i know) i can only give the container a name (i.e. atom) and the variables inside (i.e. QString, QList, QList) are not named this makes organizing the data more difficult.

This is the reason i was trying to use structures of container classes.

Hope this helps and indicates why i asked the original question.

Many thanks,

Matt

high_flyer
10th January 2011, 09:15
If i use a container class directly (as far as i know) i can only give the container a name (i.e. atom) and the variables inside (i.e. QString, QList, QList) are not named this makes organizing the data more difficult.
For this there are maps.
Have a look at QMap.
So you can do things like:


QMap<QString,atom*> m_mapAtoms;
...
atom *pAtom = new atom;
...
//Storing
m_mapAtoms["atom1"] = pAtom;

//using
pAtom = m_mapAtoms["atom1"];

mobucl
10th January 2011, 13:09
Hi high_flyer,

Thanks again. I think i see how to use this, however using


class atom
{
public:
QString type;
QList hkl
Qlist IJK
};

in the header file to create the class atom and then running the code you gave below
i get an error:

aggregate 'QMap<QString, atom*> m_mapAtoms' has incomplete type and cannot be defined

Sorry but im not sure why i get this as if i just create an instance of atom (atom atom1) it works fine.

Can you please help?

Thanks

Matt

high_flyer
10th January 2011, 13:11
Show the definition code and the code where you use the map. (not just these lines, but a bit before and after)

mobucl
10th January 2011, 13:35
HI high_flyer.

This is all the code from the header file (including the previously discussed attempts at creating nested classes and some function defs):


#ifndef ATTEMPT1_H
#define ATTEMPT1_H

//#include <QWidget>
//#include <iostream>
//#include <fstream>
//#include <string>
//#include <vector>
//#include <windows.h>
//#include <QTextEdit>
//#include <QString>
#include <QFileDialog>
//using namespace std;
//#include <QtCore/QFile>
//#include <QtCore/QTextStream>
void FileOpen(QString fileName, QVector<double>& x, QVector<QVector<double> >& y); // this is using pointers for output
void FiCalc(double lambda, double TwoThetaMin, double TwoThetaMax);
QList<QList<int> > Combinations(int a, int b, int c,int aa,int bb,int cc);
QList<double> AtomicScattering(QString Symbol,QList<float> dSpace);
namespace Ui {
class attempt1;
}

class attempt1 : public QWidget
{
Q_OBJECT

public:
explicit attempt1(QWidget *parent = 0);
~attempt1();

private:
Ui::attempt1 *ui;

private slots:
void on_save_clicked();
void on_run_clicked();
void on_load_clicked();
};

#endif // ATTEMPT1_H



class atom
{
public:
QString type;
};


class data
{
//int size;
public:
QString name; //string for standard name from CIF
// QList < QList <QList<float> > >xyz; //3d array for XYZ values from CIF
// data(int);
int size;
double aSide;
double bSide;
double cSide;
double alpha;
double beta;
double gamma;
double volume;
QList<float> dSpace; //use a float as we only want to compare to 8 significant figures
QList<QList<int> > hkl;
QList<float> TwoTheta;
QList<float> I;
atom atom1;
atom atom2;

};

The code im using in the cpp file id just what you wrote below:


QMap<QString,atom*> m_mapAtoms;
atom *pAtom = new atom;
//Storing
m_mapAtoms["atom1"] = pAtom;
//using
pAtom = m_mapAtoms["atom1"];

Is this the information you need?

thanks

Matt

Added after 19 minutes:

Sorry high_flyer I just realised i didnt include <QMap> (im still getting used to including things as in matlab you don't do this!).

I will have a look at QMap now - in your opinion is this the best way to organize data sets each containing lots of different data types?

Thanks for your help again!

Matt

FelixB
10th January 2011, 13:48
please use "code"-tags.

do you include <QMap>?

mobucl
10th January 2011, 13:51
sorry will do in future

yes include was the problem - i did notice and updated the post above about 20 mins after!

Thanks

Matt