1

Please help.. I have singleton class but can't get it's instance.

dbinfogetterdao.h

#ifndef MATRIXGETTERDAO_H
#define MATRIXGETTERDAO_H
#include <QtSql/QSqlDatabase>

namespace Ui{
    class DBInfoGetterDAO;
}

class DBInfoGetterDAO
{
    public:
        static DBInfoGetterDAO& getInstance();
    private:
        DBInfoGetterDAO();                   
        DBInfoGetterDAO(DBInfoGetterDAO const&);              
        void operator=(DBInfoGetterDAO const&); 
};

#endif // MATRIXGETTERDAO_H

dbinfogetterdao.cpp

#include "dbinfogetterdao.h"
#include <QtSql/QSqlDatabase>
#include <QDebug>
#include <QSqlError>
#include <QSqlQuery>


DBInfoGetterDAO& DBInfoGetterDAO::getInstance()
{
    static DBInfoGetterDAO instance;
    return instance;
}

DBInfoGetterDAO::DBInfoGetterDAO()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");
    db.setDatabaseName("mdpschema");
    db.setUserName("root");
    db.setPassword("password");
    bool ok = db.open();
    qDebug() << "db connection status = " << ok;
    QSqlError error = db.lastError();
    if (ok == false){
        qDebug() << "error text = " + error.text();
    }
}

I create instance like this:

   DBInfoGetterDAO dbInfoGetterDAO = DBInfoGetterDAO::getInstance(); 

Please could you explain me what I did wrong.

Boris Mitioglov
  • 1,092
  • 4
  • 16
  • 32

5 Answers5

0

your constructor is private, so you cannot create an object of your class.

Bramsh
  • 389
  • 1
  • 2
  • 14
  • I found example from here: http://stackoverflow.com/a/1008289/2015948 and there is private constructor too. – Boris Mitioglov Apr 05 '14 at 20:37
  • are you doing this in main? DBInfoGetterDAO dbInfoGetterDAO = DBInfoGetterDAO::getInstance(); – Bramsh Apr 05 '14 at 20:42
  • an other class which is inherited from this class? – Bramsh Apr 05 '14 at 20:46
  • 1
    then how can you make an object of this class in an other class? DBInfoGetterDAO dbInfoGetterDAO = DBInfoGetterDAO::getInstance(); when you do so, copy constructor will be called – Bramsh Apr 05 '14 at 20:49
  • 1
    well, I am new to OOP. I don't have any solution :( – Bramsh Apr 05 '14 at 20:53
  • I am now calling DBInfoGetterDAO::getInstance().printAllCountries(); and all works fine :) But can you explain why I can't get an DBInfoGetterDAO object? – Boris Mitioglov Apr 05 '14 at 20:58
  • when you do like this : DBInfoGetterDAO dbInfoGetterDAO = DBInfoGetterDAO::getInstance(); // you are creating an object of class DBInfoGetterDAO and assigning it an object that you get from function getInstance(), but for this constructor must be called (copy constructor). but you have made your constructor private. so how will this object be created? – Bramsh Apr 05 '14 at 21:01
  • when you create this object: DBInfoGetterDAO dbInfoGetterDAO; constructor must be called, doesn't matter you are assigning it an other object or not. you are creating an object so constructor is needed. which is private – Bramsh Apr 05 '14 at 21:05
  • 1
    ok, why does DBInfoGetterDAO dbInfoGetterDAO = DBInfoGetterDAO::getInstance().printAllCountries() variant works then? – Boris Mitioglov Apr 05 '14 at 21:09
  • well, I don't know what printAllCountries(); does :P. I told you I am new as well, if you come to know about the solution. do tell me too :) – Bramsh Apr 05 '14 at 21:13
  • 1
    ok :) printAllCountries is not a static method from DBInfoGetterDAO, so the DBInfoGetterDAO must create an instance, I think, with a private constructor – Boris Mitioglov Apr 05 '14 at 21:26
0

It seems that getInstance() method declaration is different from its definition, just change

static DBInfoGetterDAO getInstance();

into

static DBInfoGetterDAO& getInstance();

Also move class definition and class methods definitions inside Ui namespace as yo did with class forward declaration.

angelvet
  • 59
  • 4
0

You are doing it fundamentally wrong. This is not the correct way of defining singletons with Qt. I would suggest to use QGlobalStatic instead.

Instead of doing all this, you could simply do this:

Q_GLOBAL_STATIC(MyType, staticType)

Moreover, your singleton is as racey as possible. It will blow up from different threads all of a sudden.

László Papp
  • 51,870
  • 39
  • 111
  • 135
0

I added namespace 'DB' to dbinfogetterdao.h:

namespace DB {

namespace Ui{
    class DBInfoGetterDAO;
}

class DBInfoGetterDAO
{
    public:
        static DBInfoGetterDAO& getInstance();
        void printAllCountries();
        QList<QString> getAppropriateCountriesFromDB(QString property, QString site_type);
        Flightmatrix getFlightMatrix(QString site_type);
        static void printFlightMatrix(QVector< QVector< int > > matrix);
    private:
        DBInfoGetterDAO();
        DBInfoGetterDAO(DBInfoGetterDAO const&);
        void operator=(DBInfoGetterDAO const&);
        int getIndexByName(QHash<int, QString> map, QString name);

};

}

and in dbinfogetterdao.cpp I've added 'using namespace DB':

using namespace DB;

DBInfoGetterDAO& DBInfoGetterDAO::getInstance()
{
    static DBInfoGetterDAO instance;
    return instance;
}

DBInfoGetterDAO::DBInfoGetterDAO()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");
    db.setDatabaseName("mdpschema");
    db.setUserName("root");
    db.setPassword("password");
    bool ok = db.open();
    qDebug() << "db connection status = " << ok;
    QSqlError error = db.lastError();
    if (ok == false){
        qDebug() << "error text = " + error.text();
    }
}

it helped me.

Boris Mitioglov
  • 1,092
  • 4
  • 16
  • 32
0

the problem is not in the singleton implementation or due to namespace it is here

DBInfoGetterDAO dbInfoGetterDAO = DBInfoGetterDAO::getInstance();

DBInfoGetterDAO dbInfoGetterDAO is trying to create object using private constructors.

rawjean
  • 51
  • 4