IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Discussion :

design pattern Singleton

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 47
    Par défaut design pattern Singleton
    Hello'

    -> J'ai découvert les singleton, c'est ce qu'il me fallait.
    -> J'ai aucune connaissances sur le sujet, je fais que découvrir... j'aimerais savoir pourquoi ca ne marche pas
    -> pitié des mots simples dans vos reponses, je débute...

    -> mon but: rendre MainWindow singleton, et ensuite rendre SocketHandler singleton... Mais si j'y arrive une fois, je devrais pouvoir le faire deux fois.

    L'erreur qui s'affiche:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    debug/main.o(.text+0x16a): In function `Z5qMainiPPc':
    C:/dev/HighStory/main.cpp:11: undefined reference to `Singleton<MainWindow>::Get()'
    debug/sockethandler.o(.text+0x4f5): In function `ZN13SocketHandler3lolEv':
    C:/dev/HighStory/sockethandler.cpp:16: undefined reference to `Singleton<MainWindow>::Get()'
    main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include <QtGui/QApplication>
    #include "mainwindow.h"
    #include "sockethandler.h"
    #include "designpatterns.h"
     
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
     
     
    MainWindow* w=Singleton<MainWindow>::Get();
     
        w->show();
        w->showLogin();
     
     
        SocketHandler sh;
        sh.lol();
        return a.exec();
    }
    sockethandler.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #include "sockethandler.h"
    #include "global_variables.h"
    #include "mainwindow.h"
    #include "designpatterns.h"
     
    SocketHandler::SocketHandler()
    {
        _qts = new QTcpSocket();
        _qts->connectToHost(QString(QTS_CONNECT_ADDRESS),QTS_CONNECT_PORT);
        qDebug("woot connected");
    }
     
     
    void SocketHandler::lol()
    {
        MainWindow* w=Singleton<MainWindow>::Get();
        w->errorAlert("LOOL");
    }
    mainwindow.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "global_variables.h"
     
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent), ui(new Ui::MainWindowClass)
    {
        ui->setupUi(this);
    }
     
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    void MainWindow::showLogin()
    {
        // creating the login widget
        qmwLogin = new QWidget(this);
        qmwLogin->setObjectName(QString(QMW_LOGIN));
        qmwLogin->setGeometry(QRect(this->geometry().left(),this->geometry().top(),this->geometry().width(),this->geometry().height()));
        // now the controls
        leAccountID = new QLineEdit(qmwLogin);
        lePassword  = new QLineEdit(qmwLogin);
        pbLogin   = new QPushButton(qmwLogin);
        // names of em
        leAccountID->setObjectName(QString(QMW_LOGIN_ACCOUNTID));
        lePassword->setObjectName(QString(QMW_LOGIN_PASSWORD));
        pbLogin->setObjectName(QString(QMW_LOGIN_BTNLOGIN));
        // positioning
        leAccountID->setGeometry(QRect(qmwLogin->geometry().left()+100,qmwLogin->geometry().top()+100,60,20));
        lePassword->setGeometry(QRect(qmwLogin->geometry().left()+100,qmwLogin->geometry().top()+130,60,20));
        pbLogin->setGeometry(QRect(qmwLogin->geometry().left()+120,qmwLogin->geometry().top()+160,40,20));
        pbLogin->setText("Log in");
        // signals
        connect(pbLogin,SIGNAL(clicked()),this,SLOT(doLogin()));
        // show 'em
        leAccountID->show();
        lePassword->show();
        pbLogin->show();
     
        setCentralWidget(qmwLogin); // sets central widget
    }
    void MainWindow::hideLogin()
    {
        delete qmwLogin;
    }
    void MainWindow::doLogin()
    {
        QString *enteredAccountID = new QString(leAccountID->text());
        if(enteredAccountID->isEmpty() || enteredAccountID->isNull()) errorAlert(QString(ERROR_MISSING_ACCOUNTID));
        else {
            // preparating a packet to send.
            // sends it.
        }
     
    }
    void MainWindow::errorAlert(QString msg)
    {
        qmwErrorBox = new QWidget(this);
        qmwErrorBox->setGeometry(QRect(this->geometry().width()/2-150,this->geometry().height()/2-70,300,140));
        QLabel *ebMessage = new QLabel(qmwErrorBox);
        ebMessage->setGeometry(QRect(10,10,280,70));
        ebMessage->setText(msg);
        QPushButton *ebOk = new QPushButton(qmwErrorBox);
        ebOk->setGeometry(QRect(110,90,80,40));
        ebOk->setText("Ok");
        connect(ebOk,SIGNAL(clicked()),this,SLOT(errorOk()));
        qmwErrorBox->show();
    }
    void MainWindow::errorOk()
    {
        delete qmwErrorBox;
    }
    mainwindow.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #include <QtGui/QMainWindow>
    #include <QChar>
    #include <QLineEdit>
    #include <QPushButton>
    #include <QFile>
    #include <QTextStream>
    #include <QLabel>
     
    #include "designpatterns.h"
     
    namespace Ui
    {
        class MainWindowClass;
    }
    class MainWindow : public QMainWindow, public Singleton<MainWindow>
    {
        Q_OBJECT
     
        friend MainWindow* Singleton<MainWindow>::Get();
        friend void Singleton<MainWindow>::Kill();
     
    public:
        void showLogin();
        void hideLogin();
        void errorAlert(QString msg);
    public slots:
        void doLogin();
        void errorOk();
     
    private:
        MainWindow (const MainWindow&){}
        MainWindow(QWidget *parent = 0);
        ~MainWindow();
        Ui::MainWindowClass *ui;
        QWidget *qmwLogin;
            QLineEdit *leAccountID;
            QLineEdit *lePassword;
            QPushButton *pbLogin;
        QWidget *qmwErrorBox;
    };
    designpatterns.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    #include "designpatterns.h"
    template <class T> T* Singleton<T>::m_i=0;
     
     
    template <class T>  T* Singleton<T>::Get()
    {
            if(m_i==0)
            {
                    m_i=new T();
            }
            return m_i;
    }
     
    template <class T> void Singleton<T>::Kill()
    {
            delete m_i;
            m_i=0;
    }
    designpatterns.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template <class T> class Singleton
    {
    public:
            static T* Get();
            static void Kill();
    protected:
            static T* m_i;
            private:
            T& operator= (const T&){}
    };

  2. #2
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Salut,

    l'exception qui confirme la règle: le corps des fonctions (ie. le contenu de designpatterns.cpp) doit être inclus dans le même fichier que celui qui définit la classe elle-même (donc designpatterns.h).
    C'est le seul cas de figure (ie. dans les templates) où c'est obligatoire.

    A noter que le singleton n'est pas le saint Graal des patterns et c'est normalement un pattern à éviter (on l'appelle parfois 'anti-pattern') car on en arrive vite à accéder à l'objet singleton (ici la MainWindow) depuis n'importe où à tort et à travers, au lieu de se poser la bonne question tout de suite : "n'y a-t-il pas un souci dans mon architecture ?".

    références sur l'utilisation excessive de singletons :
    - en Anglais ici
    - traduction français ici

Discussions similaires

  1. Déserialisation et design pattern 'Singleton'
    Par tomnk dans le forum Persistance des données
    Réponses: 1
    Dernier message: 13/04/2009, 15h24
  2. scope application et design pattern singleton
    Par totoche dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 01/10/2008, 15h56
  3. [Singleton] Classe static ou Design Pattern Singleton ?
    Par piloupy dans le forum Design Patterns
    Réponses: 15
    Dernier message: 01/08/2008, 16h04
  4. Réponses: 1
    Dernier message: 04/07/2008, 14h53
  5. Implémentation du design pattern singleton
    Par 0pierrot0 dans le forum C++
    Réponses: 1
    Dernier message: 22/01/2008, 10h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo