Qt中的单例模式

news2024/9/22 11:38:23

QT单例类管理信号和槽函数

  • Chapter1 Qt中的单例模式
    • 一、什么是单例模式?
    • 二、Qt中单例模式的实现
      • 2.1、静态成员变量
      • 2.2、静态局部变量
      • 2.3、Q_GLOBAL_STATIC 宏
      • 实例2
    • 三、使用场景
    • 四、注意事项
  • Chapter2 QT单例类管理信号和槽函数
    • 一、创建单例类
    • 二、主界面添加组件
    • 三、组件代码绑定信号和槽
    • 四、效果图
    • 总结
  • Chapter3 Qt单例模式的消息全局响应类($$$)
    • 由来
    • 代码
      • GlobalMessageHelper.h文件
      • globalmessagehelper.cpp文件
      • DialogA.h/cpp文件
      • DialogB.h/cpp文件
      • DialogC.h/cpp文件
      • DialogD.h/cpp文件
      • main.cpp 文件
    • 运行结果
  • Chapter4 Qt全局信号通信
    • 应用场景分析
    • 功能实现1
    • 功能实现2
    • 功能实现3
    • FAQ


Chapter1 Qt中的单例模式

原文链接:https://blog.csdn.net/baidu_18624493/article/details/130573407

一、什么是单例模式?

    单例模式是一种创建型设计模式,用于确保类只有一个实例存在,并提供全局访问点以便于其他对象获取该实例。

    在单例模式中,类只能实例化一次,并提供了一个静态方法或全局访问点来获取该实例。这样可以确保在整个应用程序中只有一个实例存在,并且可以通过该实例进行操作和访问。

单例模式的特点包括:

单一实例:单例模式确保类只有一个实例存在。

全局访问点:通过静态方法或全局访问点获取单例对象,可以在任何地方访问该对象。

延迟初始化:单例对象通常在首次访问时才会被创建,实现了延迟初始化的效果。

限制对象创建:通过私有构造函数,限制其他类直接实例化单例对象。

    单例模式在很多情况下都有用处,例如在需要共享资源、管理全局状态、控制资源访问等场景下可以使用单例模式。然而,过度使用单例模式可能导致代码的可测试性和可维护性下降,因此需要谨慎使用。

二、Qt中单例模式的实现

    在Qt中,可以使用以下几种方式来实现单例模式。

2.1、静态成员变量

在类的私有静态成员变量中保存单例对象的指针,并提供一个静态方法来获取该对象。在静态方法中判断对象是否为空,如果为空则创建一个新的对象,否则返回已有的对象。这种方式保证了只有一个实例存在,并且在需要时进行延迟创建。

class Singleton {
private:
    static Singleton* instance;
 
    Singleton() {}
 
public:
    static Singleton* getInstance() {
        if (instance == nullptr) {
            instance = new Singleton();
        }
        return instance;
    }
};
 
Singleton* Singleton::instance = nullptr;

使用时,通过静态方法getInstance()获取单例对象:

Singleton* singleton = Singleton::getInstance();

优点:

  • 简单易用,容易理解和实现。
  • 延迟初始化,只在需要时才创建单例对象。
  • 在多线程环境下需要注意线程安全性。
    缺点:
  • 在多线程环境下需要额外处理线程安全性,可能需要使用互斥锁等机制来保护访问。
  • 对象的创建和销毁时机可能不受控制,可能存在资源管理的问题。

2.2、静态局部变量

在静态方法中使用静态局部变量保存单例对象的指针。静态局部变量在第一次调用时会被初始化,从而实现了延迟创建的效果。

class Singleton {
private:
    Singleton() {}
 
public:
    static Singleton* getInstance() {
        static Singleton instance;
        return &instance;
    }
};

优点:

  • 简洁,没有额外的静态成员变量。
  • 延迟初始化,只在需要时才创建单例对象。
  • 自动处理线程安全性,静态局部变量的初始化具有线程安全性。
    缺点:
  • 在多线程环境下需要注意线程安全性。
  • 对象的创建和销毁时机可能不受控制,可能存在资源管理的问题。

2.3、Q_GLOBAL_STATIC 宏

Qt 提供了 Q_GLOBAL_STATIC 宏,可以方便地定义全局的单例对象。这个宏使用了线程安全的延迟初始化机制,并提供了方便的访问方式。

class Singleton {
private:
    Singleton() {}
 
public:
    static Singleton* instance() {
        static Q_GLOBAL_STATIC(Singleton, singleton);
        return singleton;
    }
};

实例2

#ifndef CONFIG_H
#define CONFIG_H
 
class Config : public QObject {
  Q_OBJECT
 
 public:
  static Config *Instance();
 
  int doSomething()private:
};
 
#endif  // CONFIG_H
 
 
#include "config.h"
 
Q_GLOBAL_STATIC(Config, config)
 
Config *Config::Instance() { return config(); }
 
int Config::doSomething() {
}

优点:

  • 简单易用,使用宏定义即可创建全局的单例对象。
  • 延迟初始化,只在需要时才创建单例对象。
  • 自动处理线程安全性,具有线程安全的延迟初始化机制。
    缺点
  • 对象的创建和销毁时机可能不受控制,可能存在资源管理的问题。
  • 不适用于非全局范围的单例对象,只适用于全局单例对象的场景。

对于 Q_GLOBAL_STATIC 宏,Qt 提供了一种线程安全的延迟初始化机制。这是因为 Q_GLOBAL_STATIC 宏利用了 C++11 中的线程局部存储(thread-local storage)特性来实现。

线程局部存储是一种在每个线程中独立保存变量的机制,每个线程都有自己的变量实例,互不干扰。Q_GLOBAL_STATIC 宏利用这一特性,将单例对象的实例化和访问限制在每个线程的作用域内。

具体而言,Q_GLOBAL_STATIC 宏在使用时会根据 C++11 的线程局部存储特性,在每个线程中创建一个静态局部变量。每个线程都有自己的单例对象实例,并且线程之间的访问是互相隔离的,因此不会存在线程安全性问题。

在第一次访问该单例对象时,Q_GLOBAL_STATIC 宏会使用线程安全的方式进行初始化。在初始化过程中,会通过互斥锁等机制来保护对单例对象的访问,确保只有一个线程可以完成初始化过程。

通过使用线程局部存储和线程安全的初始化机制,Q_GLOBAL_STATIC 宏实现了线程安全的延迟初始化。这样,即使在多线程环境下同时访问单例对象,也能保证每个线程都能正确地获取到自己的单例对象实例,而不会引发竞争条件或其他线程安全性问题。

三、使用场景

单例模式在以下场景中通常被使用:

1、资源共享:当多个对象需要共享同一个资源时,可以使用单例模式确保只有一个实例存在,从而避免资源的重复创建和管理。

2、配置管理:单例模式可以用于管理应用程序的配置信息,例如日志配置、数据库连接配置等。通过单例模式,可以在整个应用程序中共享同一份配置数据,方便统一管理和访问。

3、对象缓存:某些需要频繁创建和销毁的对象,通过单例模式可以将这些对象缓存起来,提高性能和效率。例如线程池、数据库连接池等。

四、注意事项

在使用Qt单例模式时,需要注意以下几点:

1、线程安全性:如果在多线程环境下使用单例模式,需要确保对单例对象的访问是线程安全的。可以采用互斥锁(QMutex)或其他线程同步机制来保护对单例对象的访问。

2、生命周期管理:单例对象的生命周期通常延续整个应用程序的运行期间。确保在程序退出时,单例对象正确释放资源,避免内存泄漏。

3、耦合度控制:单例模式会引入全局状态,因此需要谨慎使用,避免过度依赖单例对象,导致代码的耦合度增加。应尽量将单例对象的使用限制在必要的范围内,遵循单一职责原则。

4、单元测试:单例对象的全局状态可能对代码的单元测试造成一定的影响。在进行单元测试时,需要注意单例对象的影响,并确保测试用例的独立性和可重复性。

5、可扩展性:在设计单例模式时,需要考虑到未来的扩展需求。如果将来需要创建多个类似的单例对象,需要设计一个可扩展的单例模式框架,以便灵活地管理和创建多个单例对象。

6、使用合适的方式:Qt提供了多种实现单例模式的方式,如静态成员变量、静态局部变量和Q_GLOBAL_STATIC宏等。根据实际需求选择合适的方式,权衡其优缺点。

Chapter2 QT单例类管理信号和槽函数

https://blog.csdn.net/qq_38491692/article/details/124623919

在QT当中,遇到主界面和多个组件槽函数绑定问题时,为了便于管理,我们可以通过单例类作为第三方来进行管理。

一、创建单例类

SignalInstance.h

#include <QObject>

class  SignalInstance:public QObject
{
	Q_OBJECT
public:
	static SignalInstance	*GetInstance();
	static void Release();//释放
	static SignalInstance *signalinstance;
 signals:
	 void send_to_windwostwo();
	 void send_to_windwosone();
private:
	SignalInstance();
};

SignalInstance.cpp

#include "SignalInstance.h"
SignalInstance* SignalInstance::signalinstance = nullptr;//初始化对象
//释放单例对象
void SignalInstance::Release()
{
	if (signalinstance != NULL)
	{
		delete signalinstance;
		signalinstance = NULL;
	}
}
SignalInstance::SignalInstance()
{
	
}
//获得单例对象
SignalInstance* SignalInstance::GetInstance()
{
	if (signalinstance == NULL)
	{
		signalinstance = new SignalInstance();
	}
	return signalinstance;
}

二、主界面添加组件

代码如下(示例):

#include <QObject>
#include<QVBoxLayout>
#include <QtWidgets/QWidget>
#include "SignalInstance.h"
#include"QtWidgets_1.h"
#include"QtWidgetsClass_2.h"
#include "instanse.h"
instanse::instanse(QMainWindow *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
	QVBoxLayout *lay = new QVBoxLayout(this);
	QtWidgets_1 *widget1 = new QtWidgets_1();
	lay->addWidget(widget1);
	ui.widget->setLayout(lay);
	QVBoxLayout *lay2 = new QVBoxLayout(this);
	QtWidgetsClass_2 *widget2 = new QtWidgetsClass_2();
	lay2->addWidget(widget2);
	ui.widget_2->setLayout(lay2);
}

三、组件代码绑定信号和槽

1.组件1

#pragma once

#include <QWidget>
#include "ui_QtWidgets_1.h"

class QtWidgets_1 : public QWidget
{
	Q_OBJECT

public:
	QtWidgets_1(QWidget *parent = Q_NULLPTR);
	~QtWidgets_1();
private slots:
	void Show();
private:
	Ui::QtWidgets_1 ui;
};

#include "QtWidgets_1.h"
#include"SignalInstance.h"
#include <QObject>
#include <QtWidgets/QWidget>
#pragma execution_character_set("utf-8")
QtWidgets_1::QtWidgets_1(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);
	connect(ui.pushButton, SIGNAL(clicked()), SignalInstance::GetInstance(), SIGNAL(send_to_windwostwo()));//绑定信号
	connect(SignalInstance::GetInstance(), SIGNAL(send_to_windwosone()), this, SLOT(Show()));//绑定槽函数
}

QtWidgets_1::~QtWidgets_1()
{

}
void QtWidgets_1::Show()
{
	ui.textEdit->setText("我是窗口2激活的");
}

2.组件2

#pragma once

#include <QWidget>
#include "ui_QtWidgetsClass_2.h"

class QtWidgetsClass_2 : public QWidget
{
	Q_OBJECT

public:
	QtWidgetsClass_2(QWidget *parent = Q_NULLPTR);
	~QtWidgetsClass_2();
private slots:
	void Show();
private:
	Ui::QtWidgetsClass_2 ui;
};


#include "QtWidgetsClass_2.h"
#include"SignalInstance.h"
#include <QObject>
#include <QtWidgets/QWidget>
#pragma execution_character_set("utf-8")
QtWidgetsClass_2::QtWidgetsClass_2(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);
	connect(SignalInstance::GetInstance(), SIGNAL(send_to_windwostwo()),this,SLOT(Show()));//绑定槽函数
	connect(ui.pushButton, SIGNAL(clicked()), SignalInstance::GetInstance(), SIGNAL(send_to_windwosone()));//绑定信号
}

QtWidgetsClass_2::~QtWidgetsClass_2()
{
}
void QtWidgetsClass_2::Show()
{
	ui.textEdit->setText("我是窗口1激活的");
}

四、效果图

在这里插入图片描述

总结

本文案例使用组件较少,当项目较大时,比如上千个控件和布局,能有效的对信号和槽进行管理。

Chapter3 Qt单例模式的消息全局响应类($$$)

原文链接:https://blog.csdn.net/sunnyloves/article/details/125234467

由来

在飞扬青云大佬的文章Qt开发经验里的第82条写道:

Qt的信号槽机制非常牛逼,也是Qt的独特的核心功能之一,有时候我们在很多窗体中传递信号来实现更新或者处理,如果窗体层级比较多,比如窗体A的父类是窗体B,窗体B的父类是窗体C,窗体C有个子窗体D,如果窗体A一个信号要传递给窗体D,问题来了,必须先经过窗体B中转到窗体C再到窗体D才行,这样的话各种信号关联信号的connect会非常多而且管理起来比较乱,可以考虑增加一个全局的单例类AppEvent,公共的信号放这里,然后窗体A对应信号绑定到AppEvent,窗体D绑定AppEvent的信号到对应的槽函数即可,干净清爽整洁。

代码

于是想办法写了一个类GlobalMessageHelper 注意这个类用的是单例的设计模式。
验证的思路是写了4个窗口ABCD,其中A点击按钮弹窗D,B点击按钮弹窗C,C里点击按钮将其中LineEdit输入的内容传递到D里去。如果普通的传递路线应该是C->B->main->A->D(当然可以直接C->D,但是如果项目里很多这种跨窗口的消息直接传递,就会形成飞扬大佬提到的复杂情况)。用GlobalMessageHelper 类后,就可以通过它实现所有sender和receiver直接连接。效果可以看下一节。

GlobalMessageHelper.h文件

// GlobalMessageHelper  h文件
#include <QWidget>
#include <QObject>
class GlobalMessageHelper : public QObject
{
  Q_OBJECT
public:

  ~GlobalMessageHelper();

  static GlobalMessageHelper *getInstance();

signals:
  void sendToAFromB(const QString &str);
  void sendToCFromD(const QString &str);
private:
  GlobalMessageHelper(QObject *parent = nullptr);
  static GlobalMessageHelper *gMessageHelper;
};

globalmessagehelper.cpp文件

// cpp文件
#include "globalmessagehelper.h"
GlobalMessageHelper *GlobalMessageHelper::gMessageHelper;

GlobalMessageHelper::GlobalMessageHelper(QObject *parent) :
  QObject{parent}
{
}

GlobalMessageHelper::~GlobalMessageHelper()
{
}

GlobalMessageHelper *GlobalMessageHelper::getInstance()
{
  if (!GlobalMessageHelper::gMessageHelper)
    GlobalMessageHelper::gMessageHelper = new GlobalMessageHelper;

  return GlobalMessageHelper::gMessageHelper;
}

DialogA.h/cpp文件

// DialogA  h文件
#include <QDialog>
#include <QWidget>
#include <QLineEdit>
class DialogA : public QDialog
{
  Q_OBJECT
public:
  DialogA(QDialog *parent = nullptr);
};


// DialogA  cpp文件
#include "dialoga.h"
#include "dialogd.h"
#include "globalmessagehelper.h"
#include <QVBoxLayout>
#include <QPushButton>
#include <QLineEdit>
#include <QDebug>
DialogA::DialogA(QDialog *parent) : QDialog(parent)
{
  setWindowTitle("DialogA");
  setMinimumSize(QSize(300, 100));
  QVBoxLayout *lay = new QVBoxLayout;
  setLayout(lay);
  QPushButton *btn = new QPushButton("BTN");
  lay->addWidget(btn);
  connect(btn, &QPushButton::clicked, this,
          [&]()
  {
    DialogD *dlg = new DialogD;
    dlg->show();
  });
}

DialogB.h/cpp文件

// DialogB  h文件
#include <QDialog>
#include <QWidget>

class DialogB : public QDialog
{
  Q_OBJECT
public:
  DialogB(QDialog *parent = nullptr);
};


// DialogB  cpp文件
#include "dialogb.h"
#include "dialogc.h"
#include <QVBoxLayout>
#include <QPushButton>
DialogB::DialogB(QDialog *parent) : QDialog(parent)
{
  setWindowTitle("DialogB");
  setMinimumSize(QSize(300, 100));
  QVBoxLayout *lay = new QVBoxLayout;
  setLayout(lay);
  QPushButton *btn = new QPushButton("BTN");
  lay->addWidget(btn);
  connect(btn, &QPushButton::clicked, this,
          [&]()
  {
    DialogC *dlg = new DialogC;
    dlg->show();
  });
}

DialogC.h/cpp文件

// DialogC  h文件
#include <QDialog>
#include <QWidget>
#include <QLineEdit>
class DialogC : public QDialog
{
  Q_OBJECT
public:
  DialogC(QDialog *parent = nullptr);

private:
  QLineEdit *line = nullptr;
  QPushButton *btn = nullptr;
};


// DialogC  cpp文件
#include "dialogc.h"
#include "globalmessagehelper.h"
#include <QVBoxLayout>
#include <QPushButton>
#include <QDebug>
DialogC::DialogC(QDialog *parent) : QDialog(parent)
{
  setWindowTitle("DialogC");
  setMinimumSize(QSize(300, 100));
  QVBoxLayout *lay = new QVBoxLayout;
  setLayout(lay);

  line = new QLineEdit;
  lay->addWidget(line);
  btn = new QPushButton("Send");
  lay->addWidget(btn);
  connect(btn, &QPushButton::clicked, this,
          [&]()
  {
    emit GlobalMessageHelper::getInstance()->sendToAFromB(line->text());
  });
}

DialogD.h/cpp文件

// DialogD  h文件
#include <QDialog>
#include <QWidget>
class QLineEdit;
class DialogD : public QDialog
{
public:
  DialogD();
  QLineEdit *line = nullptr;
};


// DialogD  cpp文件
#include "dialogd.h"
#include "globalmessagehelper.h"
#include <QLineEdit>
#include <QVBoxLayout>
DialogD::DialogD()
{
  setWindowTitle("DialogD");
  setMinimumSize(QSize(300, 100));
  QVBoxLayout *lay = new QVBoxLayout;
  setLayout(lay);
  line = new QLineEdit;
  lay->addWidget(line);
  connect(GlobalMessageHelper::getInstance(), &GlobalMessageHelper::sendToAFromB, this,
          [&](const QString &s)
  {
    Q_ASSERT(GlobalMessageHelper::getInstance() != nullptr);

    line->setText(s);
  });
}

main.cpp 文件

// main.cpp  文件

#include "globalmessagehelper.h"
#include "dialoga.h"
#include "dialogc.h"
#include "dialogb.h"

#include <QApplication>

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);

  DialogA dlgA;
  DialogB dlgB;
  dlgA.show();
  dlgB.show();
  return a.exec();
}

运行结果

在这里插入图片描述

Chapter4 Qt全局信号通信

原文链接:https://blog.csdn.net/u012790503/article/details/81950467

应用场景分析

Qt开发中经常会遇到作用域跨度比较大的对象间通信的场景,如果直接使用信号槽通过对象指针直接连接,首先需要将对象指针互相暴露出来,其中可能涉及到各种复杂的传递过程,导致程序混乱。一种解决方案是建立全局的信号中转站,实现全局范围内的便捷通信。

功能实现1

设现有对象A,需要将信号signalA()发送给对象B。

建立单例类class SIgnalStation。
在单例类中定义中转信号void transSignalA()。
在A的代码中,将A的信号与信号中转的信号连接:
A:: connect(this, SIGNAL(signalA()), SIgnalStation::instance(), SIGNAL(transSignalA()));
在对象B中连接中转信号:
B::connect(SignalStation::instance(), SIGNAL(transSignalA()), this, SLOT(…));
这样就实现了进程中任何对象间信号传递。

功能实现2

此种实现是用ID或字符串来实现对信号的索引,如下表所示:
在这里插入图片描述

通过这样的映射,可以实现更低的耦合,映射由一个管理器管理,如GlobalMsgMgr类。此类提供两个接口:

addEmit(const char *msg_id(信号ID), const char *signal(信号签名)):用于将本地信号绑定到信号ID上,本地信号触发时,自动触发所有连接到此信号ID上的槽。
addSlot(const char *msg_id(信号ID), const char *slot(槽签名)):用于将本地槽绑定到信号ID上,任意信号触发源触发此信号时,本地槽会被调用。

综上,
实现2比实现1的耦合程度更低,单从ID上看不出信号参数类型;好处是可以通过ID实现更松的耦合,甚至可以实现信号ID的比较运算。
实现1、实现2在触发信号时稍微麻烦一点,因为触发信号时,需要定义本地的信号。

功能实现3

参考:Qt使用信号槽模拟全局广播
这种方式在发送信号时较为简单,但是在定义和编译时略复杂。

个人建议,在简单应用下,使用功能实现1;在复杂应用下,使用功能实现2。

FAQ

为什么不用回调函数呢,因为信号槽可以很容易实现跨线程通信,回调函数跨线程调用需要处理竞争同步的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1134886.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

原始航片匀色调色方法

使用PhotoRC 2.0软件&#xff0c;对原始航片进行批量匀色&#xff0c;可以自动处理和人机交互&#xff0c;保留exif信息。 软件下载链接&#xff1a; https://pan.baidu.com/s/1Jj4cMpq8xzYvSa1hhozH-g?pwdndfm 提取码&#xff1a;ndfm

Spring Boot中使用JSR-303实现请求参数校验

JSR-303是Java中的一个规范&#xff0c;用于实现请求参数校验。它定义了一组注解&#xff0c;可以应用于JavaBean的字段上&#xff0c;用于验证输入参数的合法性。下面是一些常用的JSR-303注解及其介绍&#xff1a; NotNull&#xff1a;用于验证字段值不能为null。 NotEmpty&a…

RT-Thread 5. ENV添加自定义模块

代码 /* file: hello.c */ #include <stdio.h> #include <finsh.h> #include <rtthread.h> int hello_world(void) {rt_kprintf("Hello, world!\n");return 0; } MSH_CMD_EXPORT(hello_world, Hello world!)/* file: hello.h */ #ifndef _HELLO_H…

03 vi编辑器

vi编辑器的三种模式: 不同的模式下机键动作解释的意义是不一样的 编辑模式 插入模式 末行模式 文件的打开和关闭保存 移动光标

专业135总分400+西安交通大学信息与通信工程学院909/815考研经验分享

今年初试发挥不错&#xff0c;400&#xff0c;专业课135&#xff0c;将近一年复习一路走来&#xff0c;感慨很多&#xff0c;希望以下经历可以给后来的同学提供一些参考。 初试备考经验 公共课&#xff1a;三门公共课&#xff0c;政治&#xff0c;英语&#xff0c;数学。在备考…

AST反混淆实战|找出某里滑块226混淆代码隐藏的字符串

关注它&#xff0c;不迷路。 本文章中所有内容仅供学习交流&#xff0c;不可用于任何商业用途和非法用途&#xff0c;否则后果自负&#xff0c;如有侵权&#xff0c;请联系作者立即删除&#xff01; 1. 常见的字符串 在还原控制流之后&#xff0c;接下来的动作就是还原字…

高效翻译工具GPT插件的使用教程

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

【语义分割】语义分割概念及算法介绍

文章目录 一、基本概念二、研究现状2.1 传统算法2.2 深度学习方法 三、数据集及评价指标3.1 常用数据集3.2 常用指标 四、经典模型参考资料 一、基本概念 语义分割是计算机视觉中很重要的一个方向。不同于目标检测和识别&#xff0c;语义分割实现了图像像素级的分类。它能够将…

【【萌新的FPGA学习之Vivado下的仿真入门-2】】

萌新的FPGA学习之Vivado下的仿真入门-2 我们上一章大概了解了 我们所需要进行各项操作的基本框架 对于内部实现其实一知半解 我们先从基本的出发 但从FPGA 了解一下 vivado下的仿真入门 正好帮我把自己的riscV 波形拉一下 行为级仿真 step1: 进入仿真界面&#xff1a;SIMULAT…

凉鞋的 Unity 笔记 204. 语句

204. 语句 在上一篇&#xff0c;我们接触了三种常见的类型&#xff0c;如下所示&#xff1a; 这样我们算是对变量进行了一个入门年了。 其实我们除了变量&#xff0c;我们还接触了一个叫做语句的概念。 我们可以看下代码&#xff1a; using System.Collections; using Syst…

四川云汇优想教育咨询有限公司电商服务正规吗

随着抖音等短视频平台的火热&#xff0c;越来越多的消费者选择在平台上购物。四川云汇优想教育咨询有限公司也推出了抖音电商服务&#xff0c;但它的服务是否正规呢&#xff1f;本文将为您揭开真相。 首先&#xff0c;我们先来了解一下四川云汇优想教育咨询有限公司。这是一家致…

基于Java的足球赛会管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

C#,数值计算——分类与推理Phylo_wpgma的计算方法与源程序

1 文本格式 using System; using System.Collections.Generic; namespace Legalsoft.Truffer { public class Phylo_wpgma : Phylagglom { public override void premin(double[,] d, int[] nextp) { } public override double dminfn(double…

java基础篇-环境变量

java基础 编程学习的关键点、重点1.环境变量设置待续 编程学习的关键点、重点 输入输出 Java语言、C语言、Python语言、甚至SQL语言&#xff0c;都需要实战、做大量输入输出等 1.环境变量设置 1.下载jdk安装 jdk官网下载直达链接&#xff1a;https://www.oracle.com/java/te…

2.9.C++项目:网络版五子棋对战之业务处理模块的设计

文章目录 一、意义二、功能三、管理&#xff08;一&#xff09;客户端请求&#xff08;二&#xff09;websocket 四、框架五、完整代码 一、意义 将所有的模块整合在一起&#xff0c;通过网络通信获取到客户端的请求&#xff0c;提供不同的业务处理。 服务器模块&#xff0c;是…

类加载机制和双亲委派机制

文章目录 &#x1f4d5;我是廖志伟&#xff0c;一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出版社签约作者、产品软文创造者、技术文章评审老师、问卷调查设计师、个人社区创始人、开源项目贡献者。&#x1f30e;跑过十五…

winodos下使用VS2022编译eclipse-paho.mqtt.c并演示简单使用的 demo

本文演示C语言如何使用eclipse-paho.mqtt.c库&#xff0c;包含自行编译库的步骤或者下载编译好的文件。 1.下载paho.mqtt.c库源码&#xff08;zip 文件&#xff09; 到官网选择C版本的paho源码进行下载 Eclipse Paho | The Eclipse Foundation 或者到下述连接下载 Releases ec…

docker在java项目中打成tar包

docker在java项目中打成tar包 1、首先安装一个docker desktop 2、mvn install项目后&#xff0c;建立一个自己的dockerfile 这里我以我的代码举例&#xff0c;from 镜像&#xff0c;这里你也能打包好一个镜像的基础上&#xff0c;from打好的镜像&#xff0c;这里我们用openj…

【C语言初阶】 一文详解分支语句 if

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《速学C语言》《数据结构篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言结构化程序设计的三种基本结构&#x1f4ac; 分支语句 &#xff08;选择结构&#xff09;&#x1f4d1; if 语句…

平衡二叉树(AVL)

平衡二叉树 基本介绍 左旋转调整成平衡二叉树 右旋转调整成平衡二叉树 双旋转调整成平衡二叉树 上述三种旋转方式的代码实现 class Node:"""创建 Node 节点"""value: int 0left Noneright Nonedef __init__(self, value: int):self.value …