0%

install(CODE)execute_process 配合

确保 WORKING_DIRECTORY 存在

示例代码:

1
2
3
4
5
set(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR}/export)
install(CODE "
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory folder
WORKING_DIRECTORY \${CMAKE_INSTALL_PREFIX})
")

注意确保 CMAKE_INSTALL_PREFIX 存在,可能执行这段代码时还没有 install target 导致 CMAKE_INSTALL_PREFIX 还没有生成。

阅读全文 »

存储和加载指令

ldr 指令寻址之1: 地址偏移模式 (unsigned offset)

1
LDR Xd, [Xn, $offset]

首先在 Xn 寄存器的内容上加上一个 offset 偏移量后作为内存地址,加载此地址的内容到 Xd 寄存器。

ldr 指令寻址之2: 变基模式

  • 前变基模式(pre-index 模式): 先更新偏移地址然后再访问内存。
  • 后变基模式(post-index 模式):先访问内存地址然后再更新偏移地址。
1
2
3
LDR X0, [X1, #8]! // 前变基模式。先更新X1 的值为 X1+8,然后义新的X1值为地址,加载内存的值到X0

LDR X0, [X1], #8 // 后变基模式。以x1的值为地址,加载该内存地址的值到X0,然后在更新X1寄存器为X1+8

ldr 指令寻址之3: 标签(literal

PC + label offset

ldr 伪指令

1
LDR x7, =MY_LABEL

move 指令

  • 16位立即数
  • 16立即数左移16,32,48位

多字节加载和存储指令 ldp 和stp

ARM 指令概要介绍

  • A64 指令集只能运行在 aarch64 环境中
  • 所有的A64汇编指令都是 32bits
  • A64 支持全部是大写或者全部是小写的书写方式

寄存器名:

Name Size Encoding Description
Wn 32 bits 0-30 Genral-purpose register 0-30
Xn 64 bits 0-30 Genral-purpose register 0-30
WZR 32 bits 31 Zero register
XZR 64 bits 31 Zero register
WPS 32 bits 31 Current stack pointer
SP 64 bits 31 Current stack pointer
阅读全文 »

使用场景

当我们在对象函数中需要返回或者使用自己的 shared_ptr 指针时,该怎么办呢?常见的错误写法如下:用不安全的表达式试图获得 thisshared_ptr 对象, 但可能会导致 this 被多个互不知晓的所有者析构.

1
2
3
4
5
6
7
struct Bad
{
std::shared_ptr<Bad> getptr() {
return std::shared_ptr<Bad>(this);
}
~Bad() { std::cout << "Bad::~Bad() called\n"; }
};
1
2
3
4
5
{
std::shared_ptr<Bad> bp1 = std::make_shared<Bad>();
std::shared_ptr<Bad> bp2 = bp1->getptr();
std::cout << "bp2.use_count() = " << bp2.use_count() << '\n';
} // UB: Bad 对象将会被删除两次

正确写法是将定义对象公开继承 enable_shared_from_this:

1
2
3
4
5
6
class Good: public std::enable_shared_from_this<Good> // 注意:继承
{
std::shared_ptr<Good> getptr() {
return shared_from_this();
}
};
阅读全文 »

Item 21: Always have comparison functions return false for equal values.

严格弱序( strict weak ordering )

先补充下严格弱序的概念: 对两个变量 xy

  • x > y 等同于 y < x
  • x == y 等同于 !(x < y) && !(x > y)

要想严格弱序,就需要遵循如下规则:

  • 每个变量值必须等于其本身(irreflexivity):x < x 永远不能为 true
  • 不对称性(asymmetry):如果 x < y,那么 y < x 就不能为 true
  • 有序性必须可传递性:如果 x < y 并且 y < z,那么 x < z
  • 值相同必须具有可传递性:如果 x == y 并且 y == z,那么 x == z
阅读全文 »

介绍

结构

什么是Reactor模式

Reactor模式结构

  • Handles:
  • Synchronous Event Demultiplexer
  • Initiation Dispatcher
  • Event Handler
  • Concrete Event Handler

Reactor模式模块之间的交互

Reactor模式实现

Reactor模式优点

Reactor模式的缺点

  • Efficiency
  • Programming simplicity
  • Portability

Item9. Choose carefully among easing options.

一、删除特定值

  1. 对于 vectorstringdeque

    最好使用 erase-remove习惯用法:

    1
    c.erase(remove(c.begin(), c.end(), 1963, c.end()));
  2. 对于 list 容器

    直接使用 remove 方法:

    1
    c.remove(1963);
  3. 对于标准关联容器

    直接使用 erase 方法:

    1
    c.erase(1963)
阅读全文 »

介绍

Disk Arbitration framework 是一个基于 Core Foundation 的低级框架。会在磁盘出现和消失时通知您的应用程序,并让您的应用程序影响该过程。借助 Disk Arbitration,我们可以:

  • 检测何时出现新磁盘
  • 阻止挂载
  • 使用不同的标志或在不同的安装点上安装卷
  • 卸载卷
  • 观察卷的变化
阅读全文 »

焦点事件

当焦点从一个 widget 移动到另一个 widget 时,会触发 QFocusEvent 事件,这个事件会被发送给原焦点窗口和当前焦点窗口,原焦点窗口执行 focusOutEvent() ,新焦点窗口执行 focusInEvent()。 相关函数如下:

1
2
void focusInEvent(QFocusEvent *event) override;
void focusOutEvent(QFocusEvent *event) override;

焦点策略

只有可获取焦点的窗口,才有机会成为焦点窗口。比如QWidget 默认策略是 Qt::NoFocus 所以 QWidget 默认不获取焦点。Qt提供了如下接口:

1
void QWidget::setFocusPolicy(Qt::FocusPolicy policy);
阅读全文 »