boost内存池(线程安全)
#include <boost/pool/singleton_pool.hpp>
typedef boost::singleton_pool<NewData, sizeof(NewData)> NewDataPool;
NewData *p = (NewData*)NewDataPool::malloc(); 申请内存
NewDataPool::free(p); 释放
noncopyable禁止拷贝操作
#include <boost/noncopyable.hpp>
class Astr:private boost::noncopyable
{
public:
Astr(){};
virtual ~Astr(){};
};
int main()
{
Astr A;
Astr B=A; //错误禁止拷贝
Astr *p = &A; //可以
· return 0;
}
单例模板
#pragma once
#include <memory>
using namespace std;
template <class T>
class CSingleton
{
public:
static inline T* Instance();
private:
CSingleton(void){}
~CSingleton(void){}
};
/**************************************************************************
Function: Instance
Description: get singleton object
Input:
Output: -
Return: - T*
Others: -
**************************************************************************/
template <class T>
inline T* CSingleton<T>::Instance()
{
static auto_ptr<T> Ainstance;
if( 0 == Ainstance.get() )
{
if( 0== Ainstance.get())
{
Ainstance.reset ( new T);
}
}
return Ainstance.get();
}
std::set 的使用【自定义结构(两个参数)】
class SortEntrust
{
public:
bool operator()(Entrust_ptrconst &pSrc, Entrust_ptrconst &pSec)const
{
return strcmp(pSrc->m_cOrderID, pSec->m_cOrderID) >0; //按需求修改
}
};
std::set<Entrust_ptr, SortEntrust> // DayEntrust;委托的数据,SortEntrust是重载()的类
enable_shared_from_this [boost或std都有](shared_ptr 管理的对象的内部获取自己的 shared_ptr)
struct A
{
void fun()
{
shared_ptr<A> sp{this};
cout<<sp->count()<<endl;
}
};
shared_ptr<A> sp{make_shared<A>()};
sp->fun(); //输出为1
在 fun函数构造智能指针时, 我们无法确定这个对象是不是被 shared_ptr 管理着, 因此这样构造的 shared_ptr 并不是与其他 shared_ptr 共享一个计数器, 那么, 在析构时就会导致对象被重复释放, 从而引发错误.(调用了两次析构)
struct B: public std::enable_shared_from_this<B>
{
void fun()
{
shared_ptr<B> sp{shared_from_this()};
cout<<sp->count()<<endl;
}
};
shared_ptr<B> sp{make_shared<B>()};//--------------*1*
sp->fun(); //输出为2
std::bind (boost::bind) 利用bind可以传入多个参数,创建指定类型的函数
typedef boost::function<void (int, int, std::string &)> CallBack;
void DoSvc(CallBack back); //需要的是三个参数的函数
auto callFunc = [](Struct& req, int Ret, int AskType, std::string& OutStr)mutable
{
//内部可修改req的值
};
//利用bind传入四个参数(或者更多个)构造三个参数类型的函数
CallBack fun = std::bind(callFunc, req, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
DoSvc(fun );
%%的使用
char tdata[16] = { 0 };
sprintf(tdata, "%%lld.%%0%dlld", 8);
tdata的格式为%lld.%08lld
C++4种类型转换
去const属性用const_cast。
基本类型转换用static_cast。
继承多态类之间的类型转换用daynamic_cast。
不同类型的指针类型转换用reinterpreter_cast。
可变参数宏写日志
#ifndef _LOG_UTILS_H_
#define _LOG_UTILS_H_
#include <stdio.h>
#include <string.h>
#define DEBUG // log开关
#define __FILENAME__ (strrchr(__FILE__, '/') + 1) // 文件名
#ifdef DEBUG
#define LOGD(format, ...) printf("[%s][%s][%d]: " format "\n", __FILENAME__, __FUNCTION__,\
__LINE__, ##__VA_ARGS__)
#else
#define LOGD(format, ...)
#endif
#endif // _LOG_UTILS_H_
编写一个小程序测试一下:
#include <stdio.h>
#include "LogUtils.h"
int main() {
LOGD("hello world");
LOGD("%d", 10);
LOGD("%s : %d", "num", 20);
LOGD();
return 0;
}
执行结果:
[main.cpp][main][5]: hello world
[main.cpp][main][6]: 10
[main.cpp][main][7]: num : 20
[main.cpp][main][8]:
可以看到,输出的 log 已经是按照我们预设的那样,打印出了 文件名、方法、行号 这类通用信息,且实现的每行 log 自动换行。
注意:
如果需要关掉所有的 log,只需要注释掉 #define DEBUG 即可。也可以通过直接在 gcc 命令中添加 -DDEBUG 定义这个宏。
三、通用的一些宏定义解释
上面的代码中用到了一些系统提供的宏定义,这里简单的介绍一下它们的含义:
__FILE__ : 当前文件路径,注意这个是文件路径,如果我们只希望得到文件名,那么像我上面的示例中那样处理一下即可
__FUNCTION__ : 函数名,即输出这条宏命令所在的函数的名字
__LINE__ : 行号,即输出这条宏命令所在文件的第几行
__VA_ARGS__ : 可变变量,即将方法中的 "..." 替换到 __VA_ARGS__ 处,前面加上 "##" 是为了适应前面一个逗号,避免 "..." 为空时出错。