Qt|设计模式工作笔记-对单例模式进一步的理解(静态加单例实现专门收发UDP对象)

583 篇文章 127 订阅
388 篇文章 20 订阅

目录

 

理论

源码


理论

这里只说明一点,使用单例模式,私有成员里放一个成员,这个成员是一个静态成员,把构造函数都屏蔽掉(放到protected或者private中即可)使用一个flag,让其只能生成一次,因为是静态的成员,所以在各个.cpp文件里面都可以用,这样就实现了单例模式的内容,今天刚刚体会到这种功能,仿写了出这样的一套代码!

源码

程序结构如下图所示:

Qt运行截图如下:

串口调试工具运行截图如下:

源码如下:

singleudp.h

#ifndef SINGLEUDP_H
#define SINGLEUDP_H

#include <QObject>
#include <QHostAddress>

#define NoInstance 0
#define HaveInstance 1


QT_BEGIN_NAMESPACE
class QUdpSocket;
QT_END_NAMESPACE

class SingleUDP: public QObject
{
    Q_OBJECT
public:

    static int nFlag;
    static SingleUDP *createObject(const int &port);
    static void clearTheObject();
    static void sendMsg(char *msg, QHostAddress address, int peerPort);
    QUdpSocket *getUdpSocket();
    ~SingleUDP();

protected:
    SingleUDP(const int &port);
    SingleUDP(){}
    SingleUDP(const SingleUDP &singleUdp){ Q_UNUSED(singleUdp) }
    SingleUDP & operator = (SingleUDP &singleUdp){ Q_UNUSED(singleUdp) return *this; }

protected slots:
    void readPendingDatagrams();

private:
    static SingleUDP *m_instance;
    QUdpSocket *m_udpSocket;
};

#endif // SINGLEUDP_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
class QTimer;
QT_END_NAMESPACE

namespace Ui {
class Widget;
}

class SingleUDP;

class Widget : public QWidget
{
    Q_OBJECT

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

protected slots:
    void timeOut();

private:
    Ui::Widget *ui;
    SingleUDP *m_singleUDP;
    QTimer *m_timer;
};

#endif // WIDGET_H

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

singleudp.cpp

#include "singleudp.h"
#include <QUdpSocket>
#include <QMessageBox>
#include <QHostAddress>
#include <QDebug>
#include <QByteArray>

int SingleUDP::nFlag = NoInstance;
SingleUDP* SingleUDP::m_instance = NULL;

SingleUDP *SingleUDP::createObject(const int &port)
{

    if(NoInstance == nFlag){

        nFlag = HaveInstance;
        m_instance = new SingleUDP(port);
        return m_instance;
    }
    else{

        return m_instance;
    }
}

void SingleUDP::clearTheObject()
{
    if(HaveInstance == nFlag){

        nFlag = NoInstance;
        delete m_instance;
        delete m_instance->getUdpSocket();
    }
}

void SingleUDP::sendMsg(char *msg, QHostAddress address, int peerPort)
{
    if(HaveInstance == nFlag){

        m_instance->getUdpSocket()->writeDatagram(msg, 128, address, peerPort);
        return;
    }

    qDebug() << "没有实例化socket对象!";
    return;
}

QUdpSocket *SingleUDP::getUdpSocket()
{
    if(nFlag == NoInstance)
        return NULL;

    return m_udpSocket;
}

SingleUDP::SingleUDP(const int &port)
{
    m_udpSocket = new QUdpSocket;
    if(!m_udpSocket->bind(port)){

        QMessageBox::information(NULL, "提示", "端口绑定失败:" + m_udpSocket->errorString());
    }
    connect(m_udpSocket, SIGNAL(readyRead()), SLOT(readPendingDatagrams()));
}

void SingleUDP::readPendingDatagrams()
{
    while(m_udpSocket->hasPendingDatagrams()){

        QHostAddress srcAddr;
        quint16 SrcPort;
        QByteArray datagram;
        datagram.resize(m_udpSocket->pendingDatagramSize());
        m_udpSocket->readDatagram(datagram.data(), datagram.size(), &srcAddr, &SrcPort);
        qDebug() << "IP:" << srcAddr.toString() << "  port:"
                 << QString::number(SrcPort) << "数据:" << datagram;
    }
}

SingleUDP::~SingleUDP()
{

}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "singleudp.h"

#include <QTimer>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    m_singleUDP = SingleUDP::createObject(7755);
    m_timer = new QTimer;

    connect(m_timer, SIGNAL(timeout()), this, SLOT(timeOut()));
    m_timer->start(500);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::timeOut()
{
    SingleUDP::sendMsg("1234567ABCDEFG", QHostAddress("127.0.0.1"), 10000);
}

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT1995

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值