甄文超

TNT 数字生活

All Posts in 2023


多表join时条件写在where和on的区别

在开发过程中经常遇到这种情况:多表关联join时,到底限制的条件是写在where后面效率高还是写在on后面,又或者是先对表过滤使表的数据量减少,到底这三种效率哪种更高,看了一堆网上说的,都没有说到具体点上,现在对这三种情况专门做以下详细说明,你就会明白到底是怎么回事了? 干货总结:(以下只适用于left join,right join,full join,不适合inner join)1、left join where + 基表过滤条件:先对基表执行过滤,然后进行left join;2、left join where + 被关联表过滤条件:先执行left join,然后执行过滤条件;3、left join on+基表过滤条件:满足过滤的left join,不满足的后面补null,然后两集合并一起;4、left join on+被关联表过滤条件:先执行过滤条件,然后执行left join; 第 …

MS SQL

智慧课堂介绍

智慧课堂产品是一种基于人工智能和大数据技术,为学生提供个性化、智能化学习体验的教育产品。该产品已广泛应用于中小学、高中、大学等教育领域,帮助学校实现信息化教学、智能化管理和数据化分析。 一、产品特点 个性化学习:智慧课堂产品通过分析学生的学习行为和成绩数据,为每个学生提供个性化的学习计划和资源,满足不同学生的需求。 智能化辅助:智慧课堂产品具备智能识别、语音识别、自然语言处理等技术,能够自动识别学生的学习难点和问题,并提供及时、准确的辅助和指导。 互动式教学:智慧课堂产品支持多种形式的互动式教学,如在线讨论、小组合作、实时测评等,有助于激发学生的学习兴趣和主动性。 数据化分析:智慧课堂产品能够收集、分析和利用学生的学习数据,为教师提供科学、全面的教学分析报告,帮助教师优化教学方法和策略。 云端同步:智慧课堂产品采用云端技术,学生可以通过手机、平板、电脑等设备随时随地学习,实现学习资源的同步 …


connect disconnect

disconnect bool QObject::disconnect ( const QObject * sender, const char * signal, const QObject * receiver, const char *method ) 当信号与槽没有必要继续保持关联时,可以使用disconnect函数来断开连接。 在disconnect函数中0可以用作一个通配符,分别表示任何信号、任何接收对象、接收对象中的任何槽函数。但是发射者sender不能为0,其它三个参数的值可以等于0。 以下三种情况需要使用disconnect()函数断开信号与槽的关联:A、断开与某个对象相关联的任何对象     disconnect(sender, 0, 0, 0); sender-disconnect(); B、断开与某个特定信号的任何关联     disconnect( …

QT C++


autofac 循环依赖

Autofac.Core.DependencyResolutionException: An exception was thrown while activating Prj.Service.ProRequirementService -> Prj.Service.PrjListService -> Prj.Service.PrjMemosService. 循环依赖问题处理方法: 方案一 调整代码结构,不允许出现循环依赖 方案二 加上 .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies) 实测,为解决 方案三 使用Lazy public class ClassA { public string Name => "A"; private readonly Lazy<ClassB> _b = …

.NET


window系统mysql安装

1、 mysql-installer-community-8.0.31.0 2、   3、初始化 1)连接服务器: mysql -u root -p 2)看当前所有数据库:show databases; 3)进入mysql数据库:use mysql; 4)查看mysql数据库中所有的表:show tables;   5)查看user表中的数据:select Host, User,Password from user; 6)修改user表中的Host:update user set Host='%' where User='root'; 7最后刷新一下:flush privileges; …

MySQL

qt 基于统信的多媒体类库

如果出现了音频波形不显示的问题,可以先装官方推荐的库。仍然不显示时,安装多媒体库.--官方推荐sudo apt-get install gstreamerl.0-plugins-goodsudo apt-get install gstreamerl.0-plugins-basesudo apt-get install gstreamerl.0-vaapisudo apt-get install gstreamerl.0-libavsudo apt-get install gstreamerl.0-pulseaudio--QT linux 多媒体库sudo apt-get install libgl1-mesa-devsudo apt-get install gstreamerl.0-libavsudo apt-get install gstreamerl.0-plugins- …

QT

prism RequestNavigate传参

RegionManager.RequestNavigate传参说明 方法说明 // 参数: // regionName: // The name of the region where the navigation will occur. // // target: // A string that represents the target where the region will navigate. // // navigationParameters: // An instance of NavigationParameters, which holds a collection of object parameters. void RequestNavigate(string regionName, string …

.NET wpf prism

prsm 复杂对象改变,通知View的方法

viewmodel对象的属性改变时,可以使用RaisePropertyChagned通知View private void Execute_OpenPickerMemberCommand() { _dialogService.ShowDialog(DialogNames.MemberPickerDialog, null, r = { if (r.Result != ButtonResult.OK) return; var member = r.Parameters.GetValue("SelectedData"); PrjModel.Owner = member.Id; PrjModel.OwnerName = member.Name; this. …

wpf prism

Prism 非主界面使用Region

非主界面使用Region时,需要特殊处理,否则无法找region 示例: 1、在Module的View里使用Region的方法 填充Region后不再,切换 .xaml <ContentControl x:Name="groupRegion" Margin="10,5,5,5" prism:RegionManager.RegionName="RegionName"/> .cs public MainForm(IRegionManager regionManager, IContainerProvider provider) { InitializeComponent(); //新页面需要手动加入RegionManger,并更新 RegionManager.SetRegionManager(groupRegion, provider.Resolve< …

wpf prism




uos 安装git

1、首先确定linux系统中是否安装了git, 直接在命令行模式下输入git ,出现下面的界面就是安装好了的   2、# sudo apt-get install git   3、配置账号 git config --global user.name "ge-heima" git config --global user.email "754263923@qq.com" git config --global credential.helper store 查看配置信息 git config --list   4、clone git clone https://github.com/tianqixin/runoob-git-test   5、选择分支 所有分支 git branch -a 本地分支 git branch 签出出并切换分支 git checkout -b v0.9rc1 …

Linux git


INavigationAware接口

public interface INavigationAware { bool IsNavigationTarget(NavigationContext navigationContext); void OnNavigatedTo(NavigationContext navigationContext); void OnNavigatedFrom(NavigationContext navigationContext); } 当从本页面转到其它页面的时候,会调用OnNavigatedFrom方法,navigationContext会包含目标页面的URI。 当从其它页面导航至本页面的时候,首先会调用IsNavigationTarget,IsNavigationTarget返回一个bool值,简单地说这个方法的作用就是告诉Prism,是重复使用这个视图的实例还是再创建 …

wpf prism

Windows下给Git配置SSH

git安装好了之后,我们就可以注册github账号开始我们的开源旅程了。这里说明一下,git和github其实并没有特殊的关系,github只是使用git的开源代码仓库而已。前面也说到过使用git作为工具的代码仓库有很多,除了github之外还有gitlab以及国内这几年比较火的码云等等。 注册成功之后,我们进入github需要做一件事情就是配置ssh。ssh是安全外壳协议,它本身和git没什么关系,主要是为了使用它来进行安全验证。说白了为了证明你是你,为了方便根据账号做权限管理。比如阻止你clone你没有权限的代码,阻止你push代码到没有权限的远程等等。说白了,这是一个安全工具,通过它可以让我们的账号和代码更加安全。 ssh相关的细节不做过多深入,感兴趣的同学可以自行了解,我们简单说下应该怎么配置。首先我们需要使用ssh-keygen工具来生成我们的ras秘钥。ras是一种对称加密算法 …

git

Git 之 git clone 使用 https 和 ssh 的区别

https 通过 https 克隆到本地后,当再次 push 到 github 远程服务器的时候,都会要求进行账号和密码的输入 ssh ssh是一种相对安全的方式,但是需要在克隆之前先配置和添加好SSH key,当再次 push 到远程 github上面的时候就不需要进行账号密码的输入了 https 利于匿名访问,适合开源项目,可以方便被别人克隆和读取(但没有push权限); ssh 不利于匿名访问,比较适合内部项目,只要配置了SSH key即可自由实现clone和push操作。 …

git

Qt中的QByteArray和自定义结构体之间的相互转换

在Qt项目开发中,经常会碰到自定义结构体和字符数组之间的转换问题,不妨假设结构体名字为custom_struct, 字符数组名字为array_data 1. QByteArray转换为自定义结构体     custom_struct *struct_data = reinterpret_cast<custom_struct *>(array_data.data());   2. 自定义结构体转换为QByteArray    QByteArray array_data; array_data.append((char*)&struct_data, sizeof(struct_data));   未测试 …

QT C++

gdb在Linux下的安装

gdb是GNU调试器,它可以帮助程序员调试C程序,在Linux系统下可以通过安装gdb来进行程序调试。安装gdb有多种方法,下面介绍Linux下几种安装gdb的方法。 一、编译安装gdb 首先下载安装包,我们以gdb-7.7.1.tar.gz为例,可以通过以下命令进行安装: tar zxvf gdb-7.7.1.tar.gz cd gdb-7.7.1 ./configure make make install 安装完成后,在/usr/local/bin目录下就可以找到gdb二进制文件了。 --未测试 二、使用系统包管理器安装gdb 不同的Linux系统可能支持的系统包管理器类型有所不同,比如Debian使用的是dpkg,Fedora使用的是Yum,Centos使用的是RPM。需要根据你使用的系统使用相应的系统包管理器进行安装。比如在Debian系统下,首先执行以下命令搜索可用的gdb软件包 …

QT Linux

log4net .net6的应用程序标准案例

第一步 安装 通过NuGet直接搜索进行安装安装log4net 第二步 编写log4net配置参数 1.添加 log4net.config 文件并更改属性 2.编写 log4net.config &lt;?xml version="1.0" encoding="utf-8" ?&gt; &lt;configuration&gt; &lt;log4net&gt; &lt;!--定义输出到文件中--&gt; &lt;appender name="SysAppender" type="log4net.Appender.RollingFileAppender"&gt; &lt;!--日志的路径--&gt; &lt;file value="Logs/"/&gt; &lt;!--是否覆盖,默认是追加true--&gt; &lt;appendToFile …

.NET wpf

WPF Prism(六)Dialog

一、什么是Dialog 对话框实际上是我们应用程序经常用到得一个功能,类如:Show、Show Dialog。可以弹出一个我们指定得窗口,仅此而已那么在Prism当中,Dialog指的什么? Prism提供了一组对话服务,封装了常用的对话框组件的功能,例如: RegisterDialog/IDialogService (注册对话及使用对话) 打开对话框传递参数/关闭对话框返回参数 回调通知对话结果 二、创建Dialog Dialog其实也是一组用户控件,我们可以创建一个子模块,然后不需要继承IModule,继承了也没有关系,只要不加载该子模块就行,这样我们可以把他当作对话框或者子模块使用,而不需要改动太多代码。值得一提的是,默认情况下这个控件会嵌入到窗体中弹出,所以我们可以定义弹出窗体的一些属性: &lt;prism:Dialog.WindowStyle&gt; …

.NET wpf

WPF Prism(五)Navigation

一、使用场景 在普遍的业务场景当中,必不可少的是页面切换,而Prism就可以使用Navigation功能来进行页面导航,在不同的场景当中会有各种用法,例如在切换页面验证、传递参数、返回上一页、返回下一页等功能。 二、导航的使用 2.1 注册显示区域(region)这个在前面章节已做详细介绍不再赘述。 2.2 注册导航页面(View)之前的介绍中我们一般是将一个View指定到一个region中。而现在我们需要将多个View注册到导航中。例如我们现在有两个子模块(ViewAModule和ViewBModule),我们分别注册导航界面: public class ViewAModule : IModule { public void OnInitialized(IContainerProvider containerProvider) { …

.NET wpf

WPF Prism(四)MVVM

一、前言 在阅读本篇文章之前,最好有ICommand和INotifyPropertyChanged等基础知识。 二、BindableBase BindableBase抽象类实现了INotifyPropertyChanged接口,主要作用当绑定到界面的数据发生改变的时候可以通知界面进行更新。 public class ContentViewModel : BindableBase { private string _message; public string Message { get { return _message; } set { SetProperty(ref _message, value); } } } 三、Command 用于事件 …

.NET wpf

WPF Prism(三)ViewModelLocator

一、命名约定 在Prism当中,你可以基于命名约定,便能够轻松的将View和ViewMode建立关联。前提是你已经为项目创建了Views和ViewModels文件夹(这里就突出了使用模板创建的好处了)。 例如:你的页面为ViewA,那么对应的ViewModel名称为ViewAViewModel。 ​ 你的页面为HeaderView,那么对应的ViewModel名称为HeaderViewModel。 二、允许View自动装配ViewModel &lt;UserControl x:Class="Menu.Views.MenuView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/ …

.NET wpf

WPF Prism(二)Module

一、什么是模块(Module) 本质上来说,对于一个应用程序而言,特定功能的所有View、Logic、Service等都可以独立存在。那么我们称每一个独立的功能我们都可以称之为模块。 通常情况下,我们在一个项目当中的结构是这样的: 所有的模块都在一个项目中,这使得应用程序当中,我们难以区分单独的模块,它们似乎变成了一个整体。所以,当我们开始考虑划分模块之间的关系的时候,并且采用新的模块化解决方案,它的结构将变成如下: 该项目包含了一个启动页,并且在启动页当中,我们划分好了对应的区域。这个时候,我们便可以灵活的配置我们的应用程序功能。使用Prism提供的强大功能,我们可以动态的加载应用程序模块,为指定的Region动态分配内容。 二、创建模块 2.1如果安装了VS插件,则可以直接在Module,它是一个类库。创建好之后是这样的: 2.2查看HeaderModule文件 …

.NET wpf

WPF Prism(一)Region

一、什么是Region 在Prism当中,一个页面我们可以不再为其固定显示的内容,而这种概念变成了区域(Region)划分的概念。将页面显示的区域划分成N个Region,每一个Region将动态分配区域。它将负责承担我们的UI组件或者控件。 二、RegionManager类 RegionManager功能 维护区域集合提供对区域的访问合成视图区域导航定义区域 三、使用RegionManager 首先,我们需要将MainWindow的构造函数传入IRegionManager参数: public partial class MainWindow : Window { public MainWindow(IRegionManager regionManager) { InitializeComponent(); …

.NET wpf

WPF Prism框架介绍

WPF Prism框架介绍 一、什么是PrismPrism是一个用于在 WPF、Xamarin Form、Uno 平台和 WinUI 中构建松散耦合、可维护和可测试的 XAML 应用程序框架。 二、官方地址 https://github.com/PrismLibrary/Prism 基于Prism的VisualStudio扩展包模板: Prism Template Pack,下载它后可以快速创建基于Prism的项目。 三、Prism框架内容 框架中包括 MVVM、依赖注入、Command、Message Event、导航、弹窗等功能。 四、Prism知识章节 Region(区域管理) Module(模块) View Injection(视图注入) ViewModelLocationProvider(视图模型定位) Command(绑定相关) Eevent Aggregator (事件 …

.NET wpf

Qt 编译错误

1、error: &lsquo;ui_mainwindow.h&lsquo; file not found(ui头文件未创建) 问题:在刚好创建的Qt Designer Form Class类中,发现类的.cpp文件中有ui头文件未找到原因:.ui文件没有被识别到,或者.ui文件不存在,导致ui头文件未创建而报错。解决:若修改了.ui文件,随手ctrl+s保存一下,不行再将工程重新构建或重启Qt,就会生成ui头文件, …

QT

QT生成与解析JSON数据,包含JSON数组

简述 Qt5 中包含了处理 JSON 的类,均以 QJson 开头(例如:QJsonDocument、QJsonArray、QJsonObject),在 QtCore 模块中,不需要额外引入其它模块。 常用的 JSON 库 json.org 中介绍了 JSON 在各种语言中的应用,在 C/C++ 中比较常用的JSON 库主要有以下几个: JsonCpp JsonCpp 是一个 C++ 用来处理 JSON 数据的开发包。 网址:http://jsoncpp.sourceforge.net/ cJSON cJSON 是一个超轻巧,携带方便,单文件,简单的可以作为 ANSI-C 标准的 JSON 解析器。 网址:http://sourceforge.net/projects/cjson/ QJson QJson 是一个基于 Qt 的开发包用来将 JSON 数据解析成 …

QT

Qt 资源文件 qrc

前言 当Qt工程打包好发给他人使用时可能会出现一些图片不显示或者一张图片都加载不出来情况,那么可能就是他人的电脑没有这些图片资源,或者源程序加载图片的方法采用的是绝对路径的写法,与他人电脑上面图片的绝对路径不一致导致加载不出来。 通过Qt添加资源文件的方法就可以解决这个问题,而且项目打包发给别人的时候不需要把图片也一起打包,可以节省很多空间。本文就是介绍Qt如何添加资源文件并使用。 添加资源文件 右键工程文件夹&mdash;&mdash;&gt;点击添加新文件 依次选择Qt&mdash;&mdash;&gt;Qt Resource File&mdash;&mdash;&gt;choose 给资源起个名字,点击下一步,然后点击完成。 先选择添加前缀,然后把前缀改成自己需要的,或者直接用 / …

QT

QLineEdit 编辑框左侧添加小图标

方法 使用action的方法添加图标 //一、新建action QAction* userAction = new QAction(ui-nameEdit); QAction* passwordAction = new QAction(ui-numEdit); //二、给action添加icon userAction-setIcon(QIcon(":/password.png")); passwordAction-setIcon(QIcon(":/num.png")); //三、给空间添加action ui-nameEdit-addAction(userAction,QLineEdit::LeadingPosition); ui-numEdit-addAction(passwordAction, …

QT

六大复盘方法及应用实例

无论是对于企业还是个人来说,复盘都是一个能让我们快速成长的方法,尤其是项目经理和PMO,你是带领项目团队的,每一次项目的完成,都有很多经验,俗话说,最大的浪费是经验的浪费! 复盘,才有机会翻盘。反思,才有机会反转。 复盘的作用在于快速找到问题,总结经验的同时,找到工作的突破点,发现可以完善的方向。 复盘的意义:对结果进行核对,并不断回顾、反思、研究自己的行为,从中找出规律,指导自己每天进步。复盘的步骤可以分为:记录分析、反思原因、探究提升。 总结和复盘的区别: 总结主要分析成功或失败的原因; 复盘不仅可以分析成功失败的原因,还能够通过假设的推演,找到不同的方法和可能性。 一、KPT复盘法 K (Keep):  保持对项目团队的及时沟通和协作,以及有效地分配任务和提高效率的方法需要继续保持。在这次项目中成功运用的技术和工具也需要保持并继续完善和应用。 P (Problem): 在项目 …

project manage team manage

qt 移动窗体

一般情况下,当去掉窗体标题栏时,按住鼠标左键就无法实现拖动窗体;当去掉窗体标题栏时,窗体四周的边框也去掉了,此时按住鼠标左键拖动窗体四周边沿,无法实现鼠标拖动改变窗体大小。如下为Qt实现去掉窗体标题栏的代码: setWindowFlag(Qt::FramelessWindowHint); // 去掉标题栏 现在的问题是:   在去掉窗体标题栏的情况下,如何在窗体上按住鼠标左键,实现移动窗体? 2.实现方法 Qt中有个QSizeGrip类,可以很好解决1节提到的问题,关于该类的具体用法,参见Qt Assistant。   代码:   private: //virtual void mousePressEvent(QMouseEvent *e) override; void mouseReleaseEvent(QMouseEvent *e) override; …

QT

Qt QlineEdit

概述:QLineEdit 类代表编程框,它可以让用户输入一个单行文本。类似于登录窗口中的账号和密码的输入框(行编辑)1,构造函数: QLineEdit (QWidget *parent = 0); QLineEdit(const QString &contents, QWidget *parent = 0); 其中 contents 表示编辑框中显示的内容。2,属性(1)alignment 属性表示显示文本的对齐方式,相关成员函数如下: int maxLength() const; // 获取最大输入长度 void setMaxLength(Qt::Alignment flag) const; // 设置对齐方式 void setMaxLength(int len); // 设置最大输入长度 它的含义与 QLabel 类的 alignment 属性相同。maxLength 属性表 …

QT

Qt Qlabel

概述:QLabel是QT界面中的标签类,它从QFrame下继承,QLabel 类代表标签,它是一个用于显示文本或图像的窗口部件。构造函数QLabel 类支持以下构造函数: QLabel(QWidget *parent = 0, Qt::WindowFlags f = 0); QLabel(const QString &text, QWidget *parent = 0, Qt::WindowFlags f= 0); 其中第二个构造函数能够同时通过参数 text 给出要显示的文本,因此是最常用的构造方式。属性QLabel 对象的显示内容可以通过属性获取或修改,相关成员函数如下: QString text() const; // 获取显示的文本 void setText(const QString &text); // 设置显示的文本,这是一个槽 const QPixmap * …

QT

QT Creator 快捷键

F1使用方法:选中某一类或函数,按下F1,出现帮助文档  F2使用方法:选中某一类或函数,按下F2,迅速定位到该类或函数声明的地方或被调用的地方  Ctrl+鼠标滚轮的使用方法:按住Ctrl,使鼠标滚轮旋转,可调整字体的大小  Ctrl+F使用方法:(作用:查找当前文档)选中你想选的内容之后,按下Ctrl+F,会列出所有和你选的内容一样的语句  F4使用方法:在*.cpp和*.h之间切换  Ctrl+1,2,3,4,5,6使用介绍:在Welcome,Edit,Debug,Projects,Help,Output几种模式之间切换  F3作用:查找下一个你选的内容  Shift + F3作用:查找上一个你选的内容  Ctrl + Shift + F作用:弹出查找对话框  F5的作用:调试  F5: continue  shift + F5: stop debug  step over: F10 …

QT

Qt常用知识点

1、Qt获取当前时间日期或时间戳QDateTime 获取系统时间 QDateTime timeCur = QDateTime::currentDateTime();//获取系统现在的时间 设置显示格式 QString timeStr = timeCur.toString("yyyy-MM-dd hh:mm:ss ddd"); //秒 设置显示格式 QString timeStr = timeCur.toString("yyyy-MM-dd hh:mm:ss.zzz"); //毫秒 获取时间戳(毫秒) QString timestamp = QString::number(QDateTime::currentMSecsSinceEpoch()) 获取时间戳(秒) int timeT = time.toTime_t(); //将当前时间转为时间戳 2、QString与char* …

QT

qt 线程同步-互斥量(Qmutex)

在多线程应用程序中,由于多个线程的存在,线程之间可能需要访问同一个变量,或一个线程需要等待另外一个线程完成某个操作后才产生相应的动作,这时候就需要做线程同步。所以,需要线程同步情况:         1)多个线程之间访问同一个变量;         2)一个线程需要等待另外一个线程完成某个操作后才产生相应的动作。 问题引入:         示例1,使用了信号与槽机制,在产生新的骰子之后使用信号通知主线程读取新数据。如果不使用信号与槽,就需要主线程进行查询。 1、基于互斥量的线程同步         QMutex和QMutexLocker是基于互斥量的线程同步类,QMutex定义的实例是一个互斥量, QMulex主要提供3个函数。         •lock():锁定互斥量,如果另外一个线程锁定了这个互斥量,它将阻塞执行直到其他线程解锁这个互斥量。         •unlock():解锁 …

QT

QMutex更好的用法QMutexLocker类的使用

QMutexLocker简化了锁定和解锁操作。 头文件: #include <QMutexLocker> QMutexLocker类是一个方便类,简化了锁定和解锁互斥。 在复杂函数和语句或异常处理代码中锁定和解锁QMutex容易出错且难以调试。QMutexLocker可用于此类情况,以确保始终定义好互斥的状态。 QMutexLocker应在需要锁定QMutex 的函数中创建。创建QMutexLocker 时,互斥器将被锁定。您可以使用 和 解锁和重新锁定静音。如果锁定,当QMutexLocker 被销毁时,将解锁互不可用。unlock()relock() 例如,此复杂函数在进入函数时锁定QMutex,并在所有出口点解锁互斥: int complexFunction(int flag) { mutex.lock(); int retVal = 0; …

QT

C++ 异常处理

异常是程序在执行期间产生的问题。C++ 异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作。 异常提供了一种转移程序控制权的方式。C++ 异常处理涉及到三个关键字:try、catch、throw。 throw: 当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。 catch: 在您想要处理问题的地方,通过异常处理程序捕获异常。catch 关键字用于捕获异常。 try: try 块中的代码标识将被激活的特定异常。它后面通常跟着一个或多个 catch 块。 如果有一个块抛出一个异常,捕获异常的方法会使用 try 和 catch 关键字。try 块中放置可能抛出异常的代码,try 块中的代码被称为保护代码。使用 try/catch 语句的语法如下所示: try { // 保护代码 }catch( ExceptionName e1 ) { // …

C++

C++ 接口(抽象类)

C++ 接口(抽象类) 接口描述了类的行为和功能,而不需要完成类的特定实现。 C++ 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。 如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 "= 0" 来指定的,如下所示: class Box { public: // 纯虚函数 virtual double getVolume() = 0; private: double length; // 长度 double breadth; // 宽度 double height; // 高度 }; 设计抽象类(通常称为 ABC)的目的,是为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象,它只能 …

C++

C++ 数据封装

C++ 数据封装 所有的 C++ 程序都有以下两个基本要素: 程序语句(代码):这是程序中执行动作的部分,它们被称为函数。 程序数据:数据是程序的信息,会受到程序函数的影响。 封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据封装引申出了另一个重要的 OOP 概念,即数据隐藏。 数据封装是一种把数据和操作数据的函数捆绑在一起的机制,数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。 C++ 通过创建类来支持封装和数据隐藏(public、protected、private)。我们已经知道,类包含私有成员(private)、保护成员(protected)和公有成员(public)成员。默认情况下,在类中定义的所有项目都是私有的。例如: class Box { public: double …

C++

C++ 数据抽象

C++ 数据抽象 数据抽象是指,只向外界提供关键信息,并隐藏其后台的实现细节,即只表现必要的信息而不呈现细节。 数据抽象是一种依赖于接口和实现分离的编程(设计)技术。 让我们举一个现实生活中的真实例子,比如一台电视机,您可以打开和关闭、切换频道、调整音量、添加外部组件(如喇叭、录像机、DVD 播放器),但是您不知道它的内部实现细节,也就是说,您并不知道它是如何通过缆线接收信号,如何转换信号,并最终显示在屏幕上。 因此,我们可以说电视把它的内部实现和外部接口分离开了,您无需知道它的内部实现原理,直接通过它的外部接口(比如电源按钮、遥控器、声量控制器)就可以操控电视。 现在,让我们言归正传,就 C++ 编程而言,C++ 类为数据抽象提供了可能。它们向外界提供了大量用于操作对象数据的公共方法,也就是说,外界实际上并不清楚类的内部实现。 例如,您的程序可以调用 sort() 函数,而不需要知道函数 …

C++

C++ 多态

C++ 多态 多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。 C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。 下面的实例中,基类 Shape 被派生为两个类,如下所示: 实例 #include &lt;iostream&gt; using namespace std; class Shape { protected: int width, height; public: Shape( int a=0, int b=0) { width = a; height = b; } int area() { cout &lt;&lt; "Parent class area :" …

C++

[运算符重载]--C++ 类成员访问运算符 -> 重载

C++ 类成员访问运算符 -&gt; 重载 类成员访问运算符( -&gt; )可以被重载,但它较为麻烦。它被定义用于为一个类赋予"指针"行为。运算符 -&gt; 必须是一个成员函数。如果使用了 -&gt; 运算符,返回类型必须是指针或者是类的对象。 运算符 -&gt; 通常与指针引用运算符 * 结合使用,用于实现"智能指针"的功能。这些指针是行为与正常指针相似的对象,唯一不同的是,当您通过指针访问对象时,它们会执行其他的任务。比如,当指针销毁时,或者当指针指向另一个对象时,会自动删除对象。 间接引用运算符 -&gt; 可被定义为一个一元后缀运算符。也就是说,给出一个类: class Ptr{ //... X * operator-&gt;(); }; 类 Ptr 的对象可用于访问类 X 的成员,使用方式与指针的用法十分相似。例如: void f(Ptr p ) { …

C++

[运算符重载]--C++ 下标运算符 [] 重载

C++ 下标运算符 [] 重载 下标操作符 [] 通常用于访问数组元素。重载该运算符用于增强操作 C++ 数组的功能。 下面的实例演示了如何重载下标运算符 []。 实例 #include &lt;iostream&gt; using namespace std; const int SIZE = 10; class safearay { private: int arr[SIZE]; public: safearay() { register int i; for(i = 0; i &lt; SIZE; i++) { arr[i] = i; } } int&amp; operator[](int i) …

C++

[运算符重载]--C++ 函数调用运算符 () 重载

C++ 函数调用运算符 () 重载 函数调用运算符 () 可以被重载用于类的对象。当重载 () 时,您不是创造了一种新的调用函数的方式,相反地,这是创建一个可以传递任意数目参数的运算符函数。 下面的实例演示了如何重载函数调用运算符 ()。 #include &lt;iostream&gt; using namespace std; class Distance { private: int feet; // 0 到无穷 int inches; // 0 到 12 public: // 所需的构造函数 Distance(){ feet = 0; inches = 0; } Distance(int f, int i){ …

C++

[运算符重载]--C++ 赋值运算符重载

C++ 赋值运算符重载 就像其他运算符一样,您可以重载赋值运算符( = ),用于创建一个对象,比如拷贝构造函数。 下面的实例演示了如何重载赋值运算符。 实例 #include &lt;iostream&gt; using namespace std; class Distance { private: int feet; // 0 到无穷 int inches; // 0 到 12 public: // 所需的构造函数 Distance(){ feet = 0; inches = 0; } Distance(int f, int i){ feet = f; inches = i; …

C++

[运算符重载]--C++ ++ 和 -- 运算符重载

C++ ++ 和 -- 运算符重载 递增运算符( ++ )和递减运算符( -- )是 C++ 语言中两个重要的一元运算符。 下面的实例演示了如何重载递增运算符( ++ ),包括前缀和后缀两种用法。类似地,您也可以尝试重载递减运算符( -- )。 实例 #include &lt;iostream&gt; using namespace std; class Time { private: int hours; // 0 到 23 int minutes; // 0 到 59 public: // 所需的构造函数 Time(){ hours = 0; minutes = 0; } Time(int h, int m){ …

C++

[运算符重载]--C++ 关系运算符重载

C++ 关系运算符重载 C++ 语言支持各种关系运算符( &lt; 、 &gt; 、 &lt;= 、 &gt;= 、 == 等等),它们可用于比较 C++ 内置的数据类型。 您可以重载任何一个关系运算符,重载后的关系运算符可用于比较类的对象。 下面的实例演示了如何重载 &lt; 运算符,类似地,您也可以尝试重载其他的关系运算符。 实例 #include &lt;iostream&gt; using namespace std; class Distance { private: int feet; // 0 到无穷 int inches; // 0 到 12 public: // 所需的构造函数 Distance(){ feet = 0; …

C++

[运算符重载]--C++ 二元运算符重载

C++ 二元运算符重载   二元运算符需要两个参数,下面是二元运算符的实例。我们平常使用的加运算符( + )、减运算符( - )、乘运算符( * )和除运算符( / )都属于二元运算符。就像加(+)运算符。 下面的实例演示了如何重载加运算符( + )。类似地,您也可以尝试重载减运算符( - )和除运算符( / )。 实例 #include using namespace std; class Box { double length; // 长度 double breadth; // 宽度 double height; // 高度 public: double getVolume(void) { return length * breadth * height; } void …

C++

[运算符重载]--C++ 一元运算符重载

C++ 一元运算符重载 一元运算符只对一个操作数进行操作,下面是一元运算符的实例: 递增运算符( ++ )和递减运算符( -- ) 一元减运算符,即负号( - ) 逻辑非运算符( ! ) 一元运算符通常出现在它们所操作的对象的左边,比如 !obj、-obj 和 ++obj,但有时它们也可以作为后缀,比如 obj++ 或 obj--。 下面的实例演示了如何重载一元减运算符( - )。 实例 #include &lt;iostream&gt; using namespace std; class Distance { private: int feet; // 0 到无穷 int inches; // 0 到 12 public: // 所需的构造函数 Distance() …

C++

C++ 重载运算符和重载函数

C++ 重载运算符和重载函数 C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。 当您调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。 C++ 中的函数重载 在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。您不能仅通过返回类型的不同来重载函数。 下面的实例中,同名函数 print() 被用于输出不同的数据类型: 实例 #include using namespace std; class printData { …

C++

C++ 继承

C++ 继承 面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易。这样做,也达到了重用代码功能和提高执行效率的效果。 当创建一个类时,您不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类。 继承代表了 is a 关系。例如,哺乳动物是动物,狗是哺乳动物,因此,狗是动物,等等。 代码如下: // 基类 class Animal { // eat() 函数 // sleep() 函数 }; //派生类 class Dog : public Animal { // bark() 函数 }; 基类 &amp; 派生类 一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基 …

C++

C++ 类的静态成员

C++ 类的静态成员 我们可以使用 static 关键字来把类成员定义为静态的。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本。 静态成员在类的所有对象中是共享的。如果不存在其他的初始化语句,在创建第一个对象时,所有的静态数据都会被初始化为零。我们不能把静态成员的初始化放置在类的定义中,但是可以在类的外部通过使用范围解析运算符 :: 来重新声明静态变量从而对它进行初始化,如下面的实例所示。 下面的实例有助于更好地理解静态成员数据的概念: 实例 #include &lt;iostream&gt; using namespace std; class Box { public: static int objectCount; // 构造函数定义 Box(double l=2.0, double b=2 …

C++

C++ this 指针

C++ this 指针 在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址。this 指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象。 友元函数没有 this 指针,因为友元不是类的成员。只有成员函数才有 this 指针。 下面的实例有助于更好地理解 this 指针的概念: 实例 #include &lt;iostream&gt; using namespace std; class Box { public: // 构造函数定义 Box(double l=2.0, double b=2.0, double h=2.0) { cout &lt;&lt;"Constructor called." &lt;&lt; endl; length = l; …

C++

C++ 内联函数

C++ 内联函数 C++ 内联函数是通常与类一起使用。如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方。 对内联函数进行任何修改,都需要重新编译函数的所有客户端,因为编译器需要重新更换一次所有的代码,否则将会继续使用旧的函数。 如果想把一个函数定义为内联函数,则需要在函数名前面放置关键字 inline,在调用函数之前需要对函数进行定义。如果已定义的函数多于一行,编译器会忽略 inline 限定符。 在类定义中的定义的函数都是内联函数,即使没有使用 inline 说明符。 下面是一个实例,使用内联函数来返回两个数中的最大值: #include &lt;iostream&gt; using namespace std; inline int Max(int x, int y) { return (x &gt; y)? x : y; } …

C++

C++ 友元函数

C++ 友元函数 类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。 友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。 如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字 friend,如下所示: class Box { double width; public: double length; friend void printWidth( Box box ); void setWidth( double wid ); }; 声明类 ClassTwo 的所有成员函数作为类 ClassOne 的友元,需要在类 ClassOne 的定义中放置如下声明: …

C++

C++ 拷贝构造函数

C++ 拷贝构造函数 拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于: 通过使用另一个同类型的对象来初始化新创建的对象。 复制对象把它作为参数传递给函数。 复制对象,并从函数返回这个对象。 如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。拷贝构造函数的最常见形式如下: classname (const classname &amp;obj) { // 构造函数的主体 } 在这里,obj 是一个对象引用,该对象是用于初始化另一个对象的。 实例 #include &lt;iostream&gt; using namespace std; class Line { public: int …

C++

C++ 类构造函数 & 析构函数

C++ 类构造函数 &amp; 析构函数 类的构造函数 类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。 构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。 下面的实例有助于更好地理解构造函数的概念: #include &lt;iostream&gt; using namespace std; class Line { public: void setLength( double len ); double getLength( void ); Line(); // 这是构造函数 private: double length; }; // 成员函数定义,包括构造函数 Line::Line(void) { …

C++

C++ 类访问修饰符

C++ 类访问修饰符 数据封装是面向对象编程的一个重要特点,它防止函数直接访问类类型的内部成员。类成员的访问限制是通过在类主体内部对各个区域标记 public、private、protected 来指定的。关键字 public、private、protected 称为访问修饰符。 一个类可以有多个 public、protected 或 private 标记区域。每个标记区域在下一个标记区域开始之前或者在遇到类主体结束右括号之前都是有效的。成员和类的默认访问修饰符是 private。 class Base { public: // 公有成员 protected: // 受保护成员 private: // 私有成员 };   公有(public)成员 公有成员在程序中类的外部是可访问的。您可以不使用任何成员函数来设置和获取公有变量的 …

C++

C++ 类成员函数

类的成员函数是指那些把定义和原型写在类定义内部的函数,就像类定义中的其他变量一样。类成员函数是类的一个成员,它可以操作类的任意对象,可以访问对象中的所有成员。 让我们看看之前定义的类 Box,现在我们要使用成员函数来访问类的成员,而不是直接访问这些类的成员: class Box { public: double length; // 长度 double breadth; // 宽度 double height; // 高度 double getVolume(void);// 返回体积 }; 成员函数可以定义在类定义内部,或者单独使用范围解析运算符 :: 来定义。在类定义中定义的成员函数把函数声明为内联的,即便没有使用 inline 标识符。所以您可以按照如下方式定义 getVolume() …

C++

C++ 类 & 对象

C++ 类 &amp; 对象 C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计。类是 C++ 的核心特性,通常被称为用户定义的类型。 类用于指定对象的形式,是一种用户自定义的数据类型,它是一种封装了数据和函数的组合。类中的数据称为成员变量,函数称为成员函数。类可以被看作是一种模板,可以用来创建具有相同属性和行为的多个对象。 C++ 类定义 定义一个类需要使用关键字 class,然后指定类的名称,并类的主体是包含在一对花括号中,主体包含类的成员变量和成员函数。 定义一个类,本质上是定义一个数据类型的蓝图,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。 以下实例我们使用关键字 class 定义 Box 数据类型,包含了三个成员变量 length、breadth 和 height: class Box { public: …

C++

C++ 数据结构

C/C++ 数组允许定义可存储相同类型数据项的变量,但是结构是 C++ 中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。 结构用于表示一条记录,假设您想要跟踪图书馆中书本的动态,您可能需要跟踪每本书的下列属性: Title :标题 Author :作者 Subject :类目 Book ID :书的 ID 定义结构 为了定义结构,您必须使用 struct 语句。struct 语句定义了一个包含多个成员的新的数据类型,struct 语句的格式如下: struct type_name { member_type1 member_name1; member_type2 member_name2; member_type3 member_name3; . . } object_names; type_name 是结构体类型的名称,member_type1 member_ …

C++

C++ 引用

引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。 C++ 引用 vs 指针 引用很容易与指针混淆,它们之间有三个主要的不同: 不存在空引用。引用必须连接到一块合法的内存。 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。 引用必须在创建时被初始化。指针可以在任何时间被初始化。 C++ 中创建引用 试想变量名称是变量附属在内存位置中的标签,您可以把引用当成是变量附属在内存位置中的第二个标签。因此,您可以通过原始变量名称或引用来访问变量的内容。例如: int i = 17; 我们可以为 i 声明引用变量,如下所示: int& r = i; double& s = d; 在这些声明中,& 读作引用。因此,第一个声明可以读作 "r 是一个初始化为 i 的整型引用",第二 …

C++

C++ 指针

学习 C++ 的指针既简单又有趣。通过指针,可以简化一些 C++ 编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的。所以,想要成为一名优秀的 C++ 程序员,学习指针是很有必要的。 正如您所知道的,每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址。请看下面的实例,它将输出定义的变量地址: #include <iostream> using namespace std; int main () { int var1; char var2[10]; cout << "var1 变量的地址: "; cout << &var1 << endl; cout << "var2 变量的地址: "; cout << &var2 << endl; return 0 …

C++

C++ 中的类型限定符

类型限定符提供了变量的额外信息,用于在定义变量或函数时改变它们的默认行为的关键字。 限定符 含义 const const 定义常量,表示该变量的值不能被修改。 volatile 修饰符 volatile 告诉该变量的值可能会被程序以外的因素改变,如硬件或其他线程。 restrict 由 restrict 修饰的指针是唯一一种访问它所指向的对象的方式。只有 C99 增加了新的类型限定符 restrict。 mutable 表示类中的成员变量可以在 const 成员函数中被修改。 static 用于定义静态变量,表示该变量的作用域仅限于当前文件或当前函数内,不会被其他文件或函数访问。 register 用于定义寄存器变量,表示该变量被频繁使用,可以存储在CPU的寄存器中,以提高程序的运行效率。   const 实例 const int NUM = 10; // 定义常量 …

C++

c++类型转换

类型转换 类型转换是将一个数据类型的值转换为另一种数据类型的值。 C++ 中有四种类型转换:静态转换、动态转换、常量转换和重新解释转换。 一、静态转换(Static Cast) 静态转换是将一种数据类型的值强制转换为另一种数据类型的值。 静态转换通常用于比较类型相似的对象之间的转换,例如将 int 类型转换为 float 类型。 静态转换不进行任何运行时类型检查,因此可能会导致运行时错误。 实例 int i = 10; float f = static_cast&lt;float&gt;(i); // 静态将int类型转换为float类型 二、动态转换(Dynamic Cast) 动态转换通常用于将一个基类指针或引用转换为派生类指针或引用。动态转换在运行时进行类型检查,如果不能进行转换则返回空指针或引发异常。 实例 class Base {}; class Derived : …

C++


C++ 的关键字(保留字)

1. asm asm (指令字符串):允许在 C++ 程序中嵌入汇编代码。 2. auto auto(自动,automatic)是存储类型标识符,表明变量"自动"具有本地范围,块范围的变量声明(如for循环体内的变量声明)默认为auto存储类型。 3. bool bool(布尔)类型,C++ 中的基本数据结构,其值可选为 true(真)或者 false(假)。C++ 中的 bool 类型可以和 int 混用,具体来说就是 0 代表 false,非 0 代表 true。bool 类型常用于条件判断和函数返回值。 4. break break(中断、跳出),用在switch语句或者循环语句中。程序遇到 break 后,即跳过该程序段,继续后面的语句执行。 5. case 用于 switch 语句中,用于判断不同的条件类型。 6. catch catch 和 try 语句一起用于异常处理。 7. …

C++

如何使IIS支持Put、delete请求

最近因为项目发布及部署,经常遇到IIS不支持项目中PUT和delete的请求,现记录下来以防忘记。 0、问题描述:一般IIS不支持PUT和Delete请求的时候,都会报405或500的错误,如下:         一、部署环境:IIS 二、问题原因分析:在默认情况下,IIS会安装一个WebDav模块,而这个模块阻止了HTTP的PUT和Delete请求。 三、解决方案: ①删除IIS安装的WebDav模块,选择你的项目,右边有个“模块”,双击它;找到WebDavModule,删除它。   ②修改你项目的web.config ,在标签内加上以下代码。 …

Windows IIS