这里列出了自己常用的一些c/c++小技巧, 有些会有不足, 可以简单探讨一下.

32位/64位等 分类

分类: 小技巧

同理可以用于其他位, 比如16位什么的. 由于不同位的平台指针的大小可能是不同的, 所以导致一些逻辑必须分别讨论.

很多时候我们可能不会在意是移动平台还是桌面平台, 但是肯定会在意指针的大小. c++的话可以使用模板特化方便地处理, 模板特化也是c非常难以模拟的特性之一.

最简单的, 比如我们想在32位平台是用单精度浮点而64位平台使用双精度浮点:

template<int T>
struct float_helper_t{
};template<>
struct float_helper_t<4> {using float_t = float;
};template<>
struct float_helper_t<8> {using float_t = double;
};using mfloat_t = float_helper_t<sizeof(void*)>::float_t;

零代价pimpl

分类: 隐藏实现, 零代价

pimpl很好用, 但是不是零代价的. 不过对象大小是在编译器是固定(c++), 我们可以利用c++11的std::aligned_storage创建一个零代价的pimpl. 同时针对不稳定API可以用static_assert进行编译期断言.

例如WinAPI有一个SRWLOCK, 表面上是一个指针. 虽然我们可以用指针重解释, 但是作为例子可以这么实现:

// 头文件namespace detail {template<size_t> struct rwlocker_impl_info {};template<> struct rwlocker_impl_info<4> { enum { size = 4, align = 4 }; };template<> struct rwlocker_impl_info<8> { enum { size = 8, align = 8 }; };
}class CRWLocker {enum { buf_size = detail::rwlocker_impl_info<sizeof(void*)>::size };enum { buf_align = detail::rwlocker_impl_info<sizeof(void*)>::align };
protected:std::aligned_storage<buf_size, buf_align>::type m_impl;
};// 源文件// 最好进行编译期断言CRWLocker::CRWLocker() noexcept {// WinAPI 的SRWLOCKusing ui_rwlocker_t = SRWLOCK; static_assert(sizeof(ui_rwlocker_t) == buf_size, "must be same");static_assert(alignof(ui_rwlocker_t) == buf_align, "must be same");const auto locker = reinterpret_cast<ui_rwlocker_t*>(&m_impl);::InitializeSRWLock(locker);
}

对于不稳定的API, static_assert是非常重要的.

链表多态

分类: 实现技巧

基础数据结构中, 链表由于是指针的重要体现, 可以非常方便地处理多态:

------       ------       ------node   -->   node   -->   node
------       ------       ------
data#1       data#2       data#3
------------------

例如比较常用的"工厂模式"创建的各个对象可以用链表串起来:

struct Node {Node*   prev;Node*   next;
};struct Factory {Factory();Node    head;Node    tail;
};struct Obj1 : Node {int a;
};struct Obj2 : Node {float a;
};Factory::Factory() {head.prev = nullptr;head.next = &tail;tail.prev = &head;tail.next = nullptr;
}

每次添加节点可以在Factory::tail.prev处做文章. 删除节点由于有头节点与尾节点的存在非常简单:

node.prev->next = node.next;
node.next->prev = node.prev;

多态的实现, 一般来说就是c++使用的虚函数. 不过注意的是虚表指针会占用一个指针的空间, 所以和节点的布局可以有两种:

A {vtable*;node;
};B {node;vtable*;
};

一般选用A模式, B比较难实现. A模式又有一个面向对象常有的问题: 包含, 还是继承?

c++有一些自己不喜欢的东西, 这些东西都是属于, 对程序猿隐藏. A模式使用继承的话, static_cast转换Node和继承类会隐含一个偏移判断, 这个隐藏没有问题. 问题是转换前会对指针进行判断, 如果是nullptr的话, 转换后还是nullptr, 这个很合理但是自己不喜欢, 添加了一个隐藏的分支.

如果大家对C/C++感兴趣的话,可以加一下我们的学习交流Q群:637  935  295,免费领取一套学习资料和视频课程哟~

所以自己可能会使用"包含"模式, 再使用offsetof进行手动转换, 虽然offsetof对于非标准布局是UB行为, 但是实际上不是offsetof是UB, 而是非标准布局.

自己常用的C/C++小技巧相关推荐

  1. php页面开发,PHP网站开发中常用的8个小技巧

    这篇文章主要介绍了PHP网站开发中常用的8个小技巧,本文讲解了命名.使用.PHP判断Form表单是否提交.PHP 获取字符串长度.PHP超全局对象等内容,需要的朋友可以参考下 PHP是一种用于创建动态 ...

  2. 常用的一些javascript小技巧(收藏http://www.car371.com/article.asp?id=13)

    常用的一些javascript小技巧 作者:隆轩 日期:2005-12-21 字体大小: 小 中 大 //事件源对象 event.srcElement.tagName event.srcElement ...

  3. OI常用的常数优化小技巧

    注意:本文所介绍的优化并不是算法上的优化,那个就非常复杂了,不同题目有不同的优化.笔者要说的只是一些实用的常数优化小技巧,很简单,虽然效果可能不那么明显,但在对时间复杂度要求十分苛刻的时候,这些小的优 ...

  4. 盘点 Redis 常用的 10 个小技巧

    点击上方 Java后端,选择 设为星标 优质文章,及时送达 Redis 在当前的技术社区里是非常热门的.从来自 Antirez 一个小小的个人项目到 成为内存数据存储行业的标准,Redis已经走过了很 ...

  5. IAR常用快捷键及使用小技巧

    选中多行后注释快捷键:Ctrl+K 取消多行注释快捷键:Ctrl+Shift+K Tab 代码右移 Shift+Tab 代码左移  Ctrl+T           对选择区域进行自动缩进  Ctrl ...

  6. 常用的excel操作小技巧--自己用的,仅供记录

    1. 如何做下拉菜单进行选择输入 选择单元格 点击Date→Date Validation→ Allow中选择List→Source中添加你想要的列表选项→ok  2.不同数字/文本 的填充区域,显示 ...

  7. 常用的一些javascript小技巧 大全

    源地址:http://bbs.blueidea.com/thread-2201069-1-1.html 事件源对象 代码: event.srcElement.tagName event.srcElem ...

  8. 常用的一些javascript小技巧

    //事件源对象 event.srcElement.tagName event.srcElement.type //捕获释放 event.srcElement.setCapture();  event. ...

  9. 常用易忘CSS小技巧

    1 解决inline-block元素设置overflow:hidden属性导致相邻行内元素向下偏移 .wrap {display: inline-block;overflow: hiddenverti ...

最新文章

  1. 三无网站怎样通过服务器审核的,面对“三无”网站该怎么解决?
  2. 设备节点监听--走在 input 分析之前
  3. 开启注册丨EMNLP 2021论文预讲会,邀你一起共赏自然语言处理学术盛宴(日程全公开)...
  4. 轻量级web api_10个很棒的JavaScript库,提升Web开发效率
  5. 工业电脑中PCI、CPCI、PXI插槽的区别
  6. mysql监听地址的设定 —— 解决外部网址无法连接mysql的办法服务器
  7. 防火墙认证的类型——Vecloud
  8. Linux数据报文接收发送总结1
  9. Java打印整数的二进制表示(代码与解析)
  10. java swing http请求_JavaWeb核心编程之(三.5)HTTP请求和接受表单数据
  11. C# 串口接收1次数据会进入2次串口接收事件serialPort1_DataReceived,第2次进入时串口缓冲区为空
  12. 构建测试的体系化思维(高级篇)
  13. “稳拿高薪”三个专业?实际市场竞争压力大,就业困难!
  14. 常见地理知识总结的连接
  15. onvif协议之云台控制
  16. python如何去某一列的元素
  17. 电阻、电容、电感、半导体器件的失效分析!
  18. “被裁员之前,没得到任何风声,措手不及...” 一个在职6年测试工程师内心独白
  19. IE浏览器验证码不刷新
  20. Git及Github之入门到进阶

热门文章

  1. 懂技术对产品有哪些帮助?
  2. Leetcode——两数之和
  3. MySQL innosetup_jdk,tomcat,mysql,innosetup封装
  4. jfinal连接oracle_JFinal框架操作oracle数据库
  5. ajax实现下拉列表回显,layui实现下拉复选功能的例子(包括数据的回显与上传)
  6. 【操作系统】页置换算法
  7. 【Python】Matplotlib绘图中文乱码问题的解决方案
  8. 软件工程——认识方法、模型、工具和技术
  9. Windows 平台下的C++代理类(供C # 使用)
  10. 系统性能信息模块--psutil