序
总结出自己经常重复的工作,抽象简化它们,按照适合自己思维方式,整合成我们自己需要的。
偷懒就是尽可能的少写代码,实现我们需要的效果。
前两篇究其根本也是为了能够尽可能的少写代码,从而节省时间。一切为了偷懒 看似调侃,其实就是我的本心。** (^▽^) **
所以开始我的偷懒之旅吧!
![52c2e570a1e2f306785f2dcdc270ff40.png](https://img-blog.csdnimg.cn/img_convert/52c2e570a1e2f306785f2dcdc270ff40.png)
宏的特性
宏的原样展开特性,对于才接触或者不怎么喜欢使用宏的人来说,宏一般用来定义常量或者类型,仅此而已,比如:
#define PI 3.1415926#define unsigned char uchar
或者实现一些简单的函数功能,因为没有类型,有时候类似模板一样,可以输入使用不同类型的参数,比如:
#define add(x,y) (x+y)#define sub(x,y) (x-y)#define mul(x,y) (x*y)#define dev(x,y) (x/y)
我的偷懒方式
1、指针、返回值检查
平常判断指针,都会类似如下方式:
int ret = 3;int *ptr = &ret;if (ret == -1) return; if (ptr == NULL) return;
可能带打印且有返回值,便于快速分析:
int ret = 3;int *ptr = &ret;if (ret == -1){ std::cout << "ret:" << ret << std::endl; return; }if (ptr == NULL){ std::cout << "ptr:" << ptr << std::endl; return false; // 或者 -1}
可以如下实现:
#define check(var, value, ...) if (var == value) { logs(var); return __VA_ARGS__; }
使用方式如下:
void test1() // 无返回值{ int ret = 3; int *ptr = &ret; check(ret , -1); check(ptr, NULL);}int test2() // 有返回值{ int ret = 3; int *ptr = &ret; check(ret, -1, 0); check(ptr, NULL, false);}
2、指针释放销毁
指针内存释放,一般用自带的 delete 或者有自己的释放函数,假设如 free(),则方式如下:
xxx *ptr = new xxx;...if (ptr != NULL){ delete ptr; // or free(ptr); ptr = 0;}
则可简单如下定义:
#define delptr(ptr) if (ptr) {delete ptr; ptr = 0;}#define freeptr(fun, ptr) if (ptr) {fun(ptr); ptr = 0;}
对于集合型指针,则可直接如下定义:
#define delptrlist(list) for (int i = 0; i < list.size(); i++) delete list[i]; list.clear();#define delptrset(list, type) foreach (type p, list) delptr(p); list.clear();#define delptrset11(list) foreach (auto p, list) delptr(p); list.clear(); // 版本 >= c++11
3、单实例类
对于类中的一种特殊设计模式,有时候仅仅需要一个对象实例即可,可以直接简单实现如下:
#define Singleton(ClassName) static ClassName &instance() { static ClassName *m_instance = 0; if (m_instance == 0) m_instance = new ClassName; return *m_instance;}
在对需要单实例的类加上如下设置即可:
class CTest{public: Singleton(CTest) // 添加单实例宏 ~CTest(); void xxxx(); void yyyy();private: CTest();};
使用方式如下:
CTest::instance().xxxx(); CTest::instance().yyyy();
更简洁的使用形式如下:
#define ctest CTest::instance()ctest.xxxx();ctest.yyyy();
4、用于数组校验
对于串口、网络数据收发时,常有一些数据计算校验计算,有的是和、有的是亦或,可以简单归纳如下:
#define calc(dat, len, opt) ({ uchar val = dat[0]; for (int i = 1; i < len; i++) val opt dat[i]; val; })
使用方式如下:
uchar dat[30];...uchar sum = calc(dat, 30, +=);uchar xor = calc(dat, 30, ^=);
如果是集合,向量等形式,可以修改如下:
#define calcset(arr, opt) ({ uchar val = arr[0]; for (int i = 1; i < arr.size(); i++) val opt arr[i]; val; })
使用方式如下:
std::veroct array;...uchar sum = calc(array, +=);uchar xor = calc(array, ^=);
对于非 uchar 类型数据,小伙伴们是不是可以自己很容易扩展了呢!?