从源文件到可执行文件
编译器1.不同语言、不同类型CPU使用的编译器不同交叉编译器:适用不同CPU架构2.编译后生成的是.obj的目标文件【本机代码】
链接器1.将所有必要的目标文件链接起来生成exe文件2.库文件:由多个目标文件打包而成,链接时指定,可提取所需的目标文件3.无法解析外部符号:找不到包含目标变量的函数的目标文件而无法完成链接4.导入库:包含函数位于dll的信息以及dll相关信息5.静态链接库:直接链接到exe文件6.构建:编译+链接
EXE文件运行1.栈:存放局部变量以及调用函数时传递的参数2.堆:程序运行时存放任意数据3.运行时的空间:操作系统专用空间+变量空间+函数空间+栈空间+堆空间
博客部署相关问题
1.在远程仓库重新创建分支hexo,复制原分支,设置为默认分支2.将原博客目录的源文件拷贝过来,删去其中.git文件,保留忽略文件3.确保几个插件node、npm、hexo成功安装4.遇到访问仓库问题,重新生成ssh,在github上添加。5.本地和远端显示图片不全问题:①取消图片的空格②html与md自带的图片显示均可以,尽量使用md自带③可使用相对路径
小结:1.Node.js 提供 JavaScript 运行环境。
npm 用来安装 Hexo 及其依赖(如 hexo-cli)。
Hexo 基于 Node.js 开发,通过 npm 安装后,生成静态博客。
2.为何设置ssh?每次提交代码都需要输入账号和密码,很麻烦,设置ssh密钥之后,在github界面添加,你的机器就会被认为是可信赖的,这样不需要多次输入密码了。ssh是针对每台主机的。
3.ssh验证原理本地生成两个密钥——公钥与私钥,主机与远程仓库通信时,远程生成字符串根据公钥加密发回本地。本地根据私钥解密,再次发送到远程,远程根据解密后的字符串是否与源字符串等同。
初始化列表
1. 提高运算性能
分析上面的结果:
(1)第一行:Test1 t1;构造一个Test1对象;
(2)第二行:输出对应Test2构造函数中的代码,用默认的构造函数初始化对象test1 // 这就是所谓的初始化阶段
(3)第三行:输出对应Test2的赋值运算符,对test1执行赋值操作 // 这就是所谓的计算阶段
2. 必须使用
const常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化
C++封装
封装目的:将数据与函数整合,只提供接口,屏蔽细节
类内的数据可设为私有
C++继承
子类对象创建时,会先调用父类的构造函数
1.如果父类构造函数带参数
2.如果父类同时有带参和不带参的,则子类默认调用无参的
**c++**之哪些成员函数不能被继承
构造函数:在创建子类对象时,为了初始化从父类继承来的数据成员,系统需要调用其父类的构造方法。如果没有显式的构造函数,编译器会给一个默认的构造函数,并且该默认的构造函数仅仅在没有显式地声明构造函数情况下创建。
析构函数:析构函数也不会被子类继承,只是在子类的析构函数中会调用父类的析构函数。
运算符重载赋值函数:赋值运算符重载函数也不会被子类继承,只是在子类的赋值运算符重载函数中会调用父类的赋值运算符重载函数。
菱形继承问题——最顶层的父类会被两次调用
1. 数据冗余
2. 二义性
解决办法——虚继承,即两个父类虚继承顶层父类
强制类型转换
static_cast主要有如下几种用法:
用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的。
用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。(**static_cast** 可用于将 int 转换为 **char**。 但是,得到的 char 可能没有足够的位来保存整个 int 值。 同样,这需要程序员来验证 static_cast 转换的结果是否安全。)
把void指针转换成目标类型的指针(不安全!!)
把任何类型的表达式转换成void类型。(这样的转换通常用于避免编译器发出未使用变量的警告。)// static_cast_Operator.cpp// compile with: /LDclass B {};
class D : public B {};
void f(B* pb, D* pd) { D* pd ...
关于构造函数QWidget(parent)
Widget::Widget(QWidget *parent) :QWidget(parent)例子:基类子类
结果:结论:子类构造函数指定父类的构造函数会调用父类的构造函数,若不指定,则调用父类的默认构造函数
源码:结论:如果parent参数非空的话,那么该构造函数使用了其父窗口的调色板,并且发送了QChildEvent事件,这会让新的窗口成为parent所指窗口的子窗口,那么当父窗口被删除时,子窗口也会自动的被删除。
Qt文件相关(File)
1.QFile File(QDir::currentPath()+"/../Config/IDExpert.config");使用绝对路径或相对路径(注意当前路径为exe文件路径还是该文件路径)
Qt对于/和\都可以识别
2.使用QDomDocument读取xml文件的两种方式
3.用户选择特定文件QFileDialogQString QFileDialog::getOpenFileName(QWidget *parent = nullptr,const QString &caption = QString(),const QString &dir = QString(),const QString &filter = QString(),QString *selectedFilter = nullptr,Options options = 0);
4.QDomElement继承QDomNode元素、文本、注释三者有所区别为元素结点为文本节点为注释结点
5.例:<s ...
QThread用法
QThread使用的两种方法1.moveToThread()——为QObject的公有方法
继承QObject的类可使用该函数,移入新线程,经检测与创建该类的类的线程不一样
2.重写run函数
quit与exit: quit()是一个公共槽函数,可以通过信号-槽机制来触发线程退出。 当您调用quit()时,它会发送一个QThread::finished信号,这会导致线程结束执行并退出。 quit()通常与start()一起使用,以在需要时请求线程退出。
exit()用于立即终止线程的执行,不等待线程完成当前任务或清理操作,这可能导致资源泄漏或数据不一致。 exit()不会触发QThread::finished信号。
通常情况下,建议使用quit()来请求线程退出,因为它更安全,允许线程完成当前任务和执行必要的清理操作。exit()方法应该只在特殊情况下使用,例如在应用程序退出时,当您确定不需要等待线程完成,或者当您需要强制终止线程时。
