Koncepcja DataModule

0

Dla każdej jednostki potrzebuje unitu, w którym będę przechowywać różne wspólne dane np. menedżer BD.
W Delphi mamy do tego DataModule i tu coś w ten deseń chciałem zrobić:

#ifndef DM_H
#define DM_H

#include <QtSql\QtSql>

namespace Utility
{
    class DataModule
    {
    public:
        QSqlDatabase db;
        DataModule();
        ~DataModule();
    };

    DataModule DM;
}

#endif
#include "DM.h"

using namespace Utility;

DataModule::DataModule()
{  
    db = QSqlDatabase::addDatabase("QMYSQL");
    db.setDatabaseName("");
    db.setUserName("");
    db.setPassword("");
    db.setHostName("");
    db.open();
}

DataModule::~DataModule()
{
}
#ifndef FIRMA_H
#define FIRMA_H

#include <QtGui/QMainWindow>
#include <QtSql\QtSql>
#include "ui_FIRMA.h"

class Firma : public QMainWindow
{
    Q_OBJECT

public:
    Firma(QWidget *parent = 0, Qt::WFlags flags = 0);
    ~Firma();

    public slots:
        void dosmoething();

private:
    Ui::MainWindow ui;
    QSqlQuery Q;

};

#endif // AD_H
#include "DM.h"
#include "FIRMA.h"
#include <QMessageBox>

using namespace Utility;

Firma::Firma(QWidget *parent, Qt::WFlags flags)
    : QMainWindow(parent, flags), Q(DM.db)
{
    ui.setupUi(this);
    connect(Firma::ui.btnSave, SIGNAL(clicked()), this, SLOT(dosmoething()));   
}

Firma::~Firma()
{

}

void Firma::dosmoething()
{
}

Jak ominąć skutek wielokrotnego dołączania ?
Trochę jestem teoretyk, sądziłem że do tego wystarczy strażnik dołączania :)

VS2010 mówi
Error 1 error LNK2005: "class Utility::DataModule Utility::DM" ([email protected]@@[email protected]@A) already defined in DM.obj

Jak wywalę includa w Firma.cpp to wtedy jest OK.

0

Zdefiniowałeś obiekt globalny:

DataModule DM;

Kłania się słówko extern ew. static...

http://www.learncpp.com/cpp-t[...]/811-static-member-variables/
http://www.learncpp.com/cpp-tutorial/42-global-variables/

0

Static być nie może. Pisałem że jeden i ten sam obiekt - dostępny dla wszystkich.
Dałem extern DataModule DM w pliku nagłówkowym a w cpp jego definicję DataModule DM i linker się czepia że nie może znaleźć definicji.... Jak to poprawnie w końcu zrobić ?

0

Singleton?

0

Dziwne, bo singletona (jeden obiekt dla wszystkich) robi się właśnie przy pomocy static...

Zajrzyj tutaj:
http://www.cs.utexas.edu/user[...]cations/Globals-JOOP-1996.pdf
(na końcu jest najlepsze rozwiązanie)

0

zrobiłem takiego singletona.

#ifndef DM_H
#define DM_H

#include <QtSql\QtSql>

namespace Utility
{
    class DataModule
    {
    private:
        DataModule(const DataModule&);
    public:
        QSqlDatabase db;
        DataModule();
        ~DataModule();
        static DataModule& Instance();
    };
}

#endif

I potem sobie QSqlQuery inicjuje poprzez

Q(DataModule::Instance().db)

Czy taka koncepcja już jest OK ?
@Vpiotr, te z Pdfa trochę zakręcone mi się wydają w stosunku do tego co mi potrzebne : >

0

Bardziej:

#ifndef DM_H
#define DM_H

#include <QtSql\QtSql>

namespace Utility
{
        class DataModule
        {
        private:
                DataModule();
        public:
                QSqlDatabase db;
                ~DataModule();
                static DataModule& Instance();
        };
}

#endif
0

Wersja ze wskaźnikiem umożliwia wykrycie próby powtórnego utworzenia obiektu.

@maciejmt: rzeczywiste singletony są bardziej wykręcone :)

coś po krótce pod twój przykład (pisane na sucho):


// DataModule.h
class DataModule
        {
        public:
                DataModule();
                ~DataModule();
               static DataModule &getInstance();
               QSqlDatabase &getDb();
        private:
                QSqlDatabase db;
                static DataModule *instance;               
        };

// DataModule.cpp
// tu mogłem coś pokręcić
static DataModule *DataModule::instance = NULL;               

DataModule::DataModule() {
  if (instance == NULL) {
    instance = this;
  } 
}

DataModule::~DataModule() {
  if (instance == this) {
    instance = NULL;
  } 
}

DataModule &DataModule::getInstance()
{
  return *instance;
}

QSqlDatabase &DataModule::getDb()
{
  return db;
}

// użycie:
Q(DataModule::getInstance().getDb())
0

A nie łatwiej:

DataModule &DataModule::getInstance()
{
  static DataModule instance;
  return instance;
}
0

No mam tak jak wyżej i wydaje się działać cacy.
Generalnie do tego co pisałem w 1 poście wystarczyło tylko opakować w static, czyli te 4 linijki i wsio.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0