C++类设计最佳实践指南
构造函数的职责
不要再构造函数中调用虚函数,也不要在无法报出错误的时候进行可能失败的初始化
构造函数不应该调用虚函数,考虑一个工厂函数或者Init()方法
缺省实现的构造函数,操作符或者析构函数等,要用=default,或者=delete显式说明
=default 显式要求编译器生成函数的一个默认版本,对于构造函数而言(尤其是拷贝/移动构造函数中),可以减轻编码负担。
此外,使用=default还可以显示指定构造函数的权限,以及保持类的特性(如trivial、POD)。
隐式类型转换相关
不要定义隐式类型转换,对于转换运算符和单参数构造函数,用explict 关键字
不要提供隐式类型转换,可以用ToFloat() 等函数替代
隐式类型转换允许某一个类型的对象被用于另一...
c++ 作用域/命名空间相关最佳实践
命名空间相关
在.cc 文件内部使用匿名空间或者static声明
禁用 using namespace … 可以使用 using type alias
禁用 inline namespace
内联空间的名字可以被外部使用,和命名空间作用相违背
不要在头文件中定义空间别名
头文件中引入的namespace 都会成为公开api的一部分
src中,namespace 应该包裹住除了#include 宏定义和其他namespace中前置声明以外的所有代码
不要在std:: 空间声明任何东西,包括前置声明
做法的结果未被定义, 不好移植,要直接引用头文件
内部连接性相关
.cc 中定义一个不需要被外部引用的变量的时候,需要放在匿名空间或者static, 但.h 中不要这么...
C++头文件最佳实践指南:从自足性到包含顺序
头文件相关的c++ guide
头文件要Self-contained
头文件要能够自给自足,即 self contained, 头文件本身以来的其他头文件,需要全部包含
也就是说,需要保证 在包含该头文件后,出于易维护性考虑,可以不需要引入其它头文件,就可以保证编译通过
例如
// foo.h
#ifndef FOO_H_
#define FOO_H_
// print_str 接口中的入参是 string 类型
// 所以要求在 这加上 头文件引用
#include <string>
void print_str(const std::string& input);
#endif // A_H_
保证引用foo.h 的地方不用添加 #include...
C++三角函数优化实践-从std::atan2到NEON加速
性能分析
火焰图发现std::atan2 存在平顶
性能优化
cv::fastAsan2 函数替换
之前用的std::atan2 性能不理想,项目中已经有opencv库,查阅资料cv::fastAsan2 更快,具体参考
https://blog.csdn.net/u014629875/article/details/97817442
https://blog.csdn.net/lien0906/article/details/49587759
cv::fastAsan2 实现原理
核心实现:
static const float atan2_p1 = 0.9997878412794807f*(float)(180/CV_PI);
static const float ...
深入剖析C++虚函数机制:从vtable到动态绑定
虚函数的实现
虚函数通过虚函数表和虚函数指针实现的,但是具体是如何利用这个表和指针进行多态调用的呢?
可以思考如下问题:
虚函数指针在哪? 干什么用的?
什么是虚函数表? 表-》信息 虚函数表-》什么信息的? 有什么用?
A 类 a 对象 b c 成员 a对象内存布局是什么样?
探究虚函数表
没有虚函数的类
demo.cc
#include<iostream>
using namespace std;
class Base{
public:
Base():m_base(0),m_base1(' '){};
void test() const { cout<&l...
详解C++函数重载的实现原理、名称修饰规则、编译器处理机制
引入
c++ 相比c有一个新特性就是overload 又名函数重载,是c++静态多态或者编译多态的实现
但是c不行,
c 语言中的函数名处理
c程序在汇编过程中,编译器会收集全局符号并生成全局符号表
符号表即,讲符合与其地址一一对应的表哥称为符号表,
在汇编的过程中我们生成了多个符号表,但最后我们只能有一个符号表,所以在链接过程中要对符号表进行合并。在合并的过程中发现同一个函数出现了两次
C++的名字修饰(name mangling/name decoration)
C++如何支持函数重载呢?
编译器会根据函数名和参数类型生成修饰后的函数名,每个重载函数都具有唯一的修饰名称。例如:
例如:
int add(int a, int b){return a+b;}
doubl...
面向高性能C++优化-内存管理、实时性保证、CPU亲和性等深度指南
为了减少不确定性,固定时延,避免内存使用的不确定性,以下是一些推荐做法。
1.mlockall() 锁定内存
调用mlockall()在初始化时锁定进程的虚拟内存,包括代码段、数据段、堆和栈,防止不确定的内存回收。
内存回收是可能会把只读映射的代码段区域回收掉,用到时再触发异常,重新从文件系统加载,重而引入了不确定的延迟。
mlockall(MCL_CURRENT | MCL_FUTURE )
这可以防止代码段意外回收后重新加载造成的不确定延迟。
注:
对于链接了多个库的大型应用,可以只锁定关键代码区域。
另外一个手段,初始化时malloc一块大内存,mlock住,再释放掉,后面再有malloc不再产生缺页中断。
2.malloc
libc中的malloc函数,...
C++高性能-vector优化、运算符选择、循环优化、内联函数
c++ vector指定大小,直接用下标而非pushback
指定大小,避免vector在添加新元素时频繁重新分配内存和拷贝数据。
每次只使用push_back添加元素,vector会频繁的重新分配内存并拷贝数据来维持连续存储,影响效率。
用emplace back替代pushback
push_back在添加元素时,需要先构造元素,再移动或拷贝到vector的末尾。
而emplace_back直接在vector末尾构造传入的参数为新的元素,避免了拷贝或移动构造的开销。
所以当添加自定义类对象到vector时,使用emplace_back可以提高效率:
用乘法代替除法 用& 代替%
int x = a / b;
// 乘法运算
int x = a * (1.0/b...
共计 128 篇文章,16 页。