C-编译与链接
C编程的基本策略是使用程序将源代码文件转换为可执行文件。通过编译和链接来完成这个过程:(1). 编译器:将源文件转换(或翻译)为中间文件;
中间文件有多种形式,最为普遍的形式,就是将源代码转为机器语言代码,并保存到目标代码文件中。
(2). 链接器:将中间文件和其他文件(预编译的库文件代码、系统的标准启动代码)合并,生成可执行文件。
编译后的目标文件中是翻译后的机器码,无法直接运行,还缺少启动代码(startup code)和库函数。①. 启动代码是程序和操作系统之间的接口,且Windows和Linux系统所需要的启动代码不同,因此这些系统处理程序的方式也不同。②. 所有的C程序都要使用C标准库中的函数,如printf()。这些函数都存储在库文件中,库文件中有许多函数的目标代码。链接器将编译生成的目标代码、系统的标准启动代码和库代码合并成一个文件,即可执行文件,该文件也是由机器语言指令组成。为了减少体积,链接器只会合并程序中使用到的库函数代码。
这种分而治之的方式,对程序进行了模块化,可以独立编译单独模块,再合并已编译的模块。若只更改了某个模块,只需重新编译此模块,无需重新编译 ...
QT-元对象系统
元对象系统简介Qt的元对象系统(The Meta-Object System)是Qt框架的核心特性之一,它为Qt提供了反射功能和动态属性管理。这个系统使得Qt能够在运行时处理对象的信息和特性,支持信号与槽机制、动态属性系统、运行时识别类型信息等功能。
元对象系统基于以下3点:
Object类:给所有使用元对象系统的对象提供了一个基类;
Q_OBJECT:用于启用元对象特性,写在类声明的私有部分中;
元对象编译器moc:为每个QObject子类提供实现元对象特性所需的代码。
moc是怎么工作的?moc读取一个c++源文件(如demo.cpp),若发现源文件中包含Q_OBJECT宏的类声明,就会生成另一个c++源文件(如moc_demo.cpp),其中包含每个类的元对象代码。生成的源文件编译并链接到类的实现中(也可以include到类的源文件中)。
QObject类创建和销毁QObject::QObject(QObject* parent = nullptr)构造一个QObject对象。
指定父对象:对象的父对象可看作对象的所有者,当父对象被销毁时,其析构函数也会销毁所有子对象; ...
QT-元对象编译器moc
在Qt中有一个元对象系统,该系统通过扩展C++,提供了信号与槽机制(事件处理)和属性系统。为了支持这些新特性,Qt引入了元对象编译器(Meta-Object Compiler,MOC),用来解析头文件并生成moc_className.cpp,将其与其他文件一起编译,实现元对象系统的基本功能。
MOC的工作原理MOC会去读取C++的源文件,寻找qt特定宏(如Q_OBJECT,Q_PROPERTY,signals,slots等),当它找到这些宏时,就会生成一个moc_className.cpp,其中包括了类的元信息,然后将这个文件以某种方式编译和链接到应用程序中。MOC生成的代码主要有:
元对象代码:指对象的信息,如类名、超类名、方法、属性、信号、槽。
信号和槽的实现:实现了信号槽机制,允许对象之间进行低耦合通信。
动态属性系统代码:允许在运行时内省和修改对象的属性。
案例定义一个类XObject,为了让该类可以使用元对象系统,类定义中添加了Q_OBJECT宏。
XObject.h
12345678910111213141516171819202122#ifndef XOBJECT_ ...
QT-QObject-d指针
二进制兼容QT的源文件中,包含许多Q_D和Q_Q宏,这两个宏是d指针(d-pointer,也称不透明指针,the opaque pointer)的设计模式的一部分,其可以做到:
对用户隐藏库的实现细节;
实现二进制兼容(可以在不破坏二进制兼容性的情况下,对库进行实现的更改)。
什么是二进制兼容?什么是源代码兼容?一个动态链接到旧版本库下运行的程序,在无需经过重新编译的情况下,仍然能够在新版本库下继续运行,这种库称为二进制兼容动态库;一个动态链接到旧版本库下运行的程序,在不需要修改程序源代码,但需要经过重新编译的情况下,才可以在新版本的库下继续运行,这种库称为源代码兼容动态库;如何做到二进制兼容?要使得一个dll或so能做到二进制兼容,就要求其中的每一个结构和每一个对象的数据模型保持不变(如增加或删除类的数据成员,就会影响对象的数据模型),若发生变动,其会导致原有的数据成员在对象数据模型中的位移发生变化,那么编译后的新版本库很大概率会使得程序运行崩溃。因此,为了使得增删类数据成员后对象数据模型也不会发生变化,通常有以下做法:
预先分配若干保留空间以备用(做法死板,因为不知道未来需要扩 ...
CPP-STL-vector容器
vector容器vector是一个长度可变的数组,支持动态扩容,因此其中的元素都存储在堆上。vector是一个模板类,第一个模板参数是数组元素的类型。如:声明一个数组arr。其元素数据类型为int:
1234567#include <vector>using namespace std;int main(){ vector<int> arr; return 0;}
构造函数 和 size()vector可以在构造时指定初始长度,通过size()获取数组的长度。这个显式构造函数,默认会将所有元素都初始化为对应数据类型的初始值,无需手动memset()。
12345678910111213#include <vector>#include <iostream>using namespace std;int main(){ /* 构造函数:explicit vector(size_t n); 元素个数:size_t size() const noexcept; */ vector<int> arr ...
[linux] 环境变量
Linux环境变量bash shell 使用环境变量 来存储 shell会话和工作环境的相关信息。环境变量允许在内存中存储数据,使得shell中运行的程序或脚本能够轻松访问到这些数据。因此,环境变量也是一种数据持久化的方式。bash shell提供了2种环境变量:全局环境变量和局部环境变量
局部环境变量所谓局部环境变量,就是只对定义它的shell会话可见。Linux系统也默认定义了一部分标准的局部环境变量。
查看局部环境变量Linux无法只查看系统有哪些局部变量。Linux提供了set命令,可以显示特定进程的所有环境变量(包括全局变量、局部变量、用户自定义变量和局部shell函数);
1234567891011121314151617181920212223242526272829303132333435363738394041424344root@smith-PC:~# setBASH=/bin/bashBASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:extquote:force_fignore:hist ...
[linux] 常用命令(1)
查看文件与目录cdlsfile:查看文件类型file命令用来确定文件的类型。
1file filename
调用file命令会打印出文件内容的简短说明。如:
1file hello.txt
less:查看文件内容less命令用来查看文件内容。
1less filename
less命令还可以使用键盘命令,通过键盘命令可以对文本内容进行前后翻页、逐行查阅和向下查找等。
键盘命令
功能
PAGE UP 或 b
向上翻页
PAGE DOWN 或 Spacebar
向下翻页
⬆
向上一行
⬇
向下一行
G
跳转至文件末尾
1G 或 g
跳转至文件开头
/charecters
向前查找指定字符串
n
向前继续查找下一个指定字符串
h
显示帮助
q
退出less
符号链接1. 什么是符号链接?在使用ls查阅部分文件时,有时候会遇到以下文件:
1234lrwxrwxrwx 1 root root 19 9月 2 15:32 libAccount.so -> libAccount.so.1.0.0*lrwxrwxrw ...
