实用处理技巧¶
1 内存泄漏检测方法¶
下面代码中#define _CRTDBG_MAP_ALLOC
宏作用是让内存泄漏信息更完善,只适合malloc分配内存,用new不产生额外信息
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
int main()
{
//方法一:在程序开始位置加上 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
int* i1 = new int(1);
int* i2 = (int*)malloc(4);
//方法二:在程序结束位置加上 _CrtDumpMemoryLeaks();
_CrtDumpMemoryLeaks();
}
2 如何把函数存进容器中¶
2.1 1.针对函数声明函数指针¶
作用:函数指针是用来作为容器的模板类型 - 假设要定义的函数如下
string* fun1(int)
{
return new string("fun1");
}
- 对应函数指针声明如下
typedef string* (*pf)(int);
2.2 2.定义容器类型¶
注意:容器是函数指针类型
//向量类型
vector<pf> v;
//map类型
map<string, pf> mpf;
2.3 3.将函数名或lambda表达式存入容器¶
- map插入函数方法
//map中插入函数
mpf.insert(make_pair("1", fun1));
//map中插入lambda表达式
mpf.insert(make_pair("3", [](int)->string* {return new string("fun3"); }));
- vector插入函数方法
v.push_back(fun1);
v.push_back([](int)->string* {return new string("fun3"); });
2.4 4.使用容器类函数¶
- map中函数使用
if (it != mpf.end)
{
string* pstr = it->second(1);
delete pstr;
}
- vector中函数使用
v[0](1);
2.5 完整测试代码¶
#include <map>
#include <vector>
#include <string>
using namespace std;
typedef string* (*pf)(int);
vector<pf> v;
map<string, pf> mpf;
string* fun1(int)
{
return new string("fun1");
}
string* fun2(int)
{
return new string("fun2");
}
int setFun()
{
v.push_back(fun1);
v.push_back([](int)->string* {return new string("fun3"); });
mpf.insert(make_pair("1", fun1));
mpf.insert(make_pair("2", fun2));
mpf.insert(make_pair("3", [](int)->string* {return new string("fun3"); }));
return 1;
}
int main(int argc, char* argv[])
{
setFun();
map<string, pf>::iterator it= mpf.find("3");
if (it != mpf.end)
{
string* pstr = it->second(1);
delete pstr;
}
v[0](1);
}
3 如何设计一个类仅有一个实例¶
4 C++可以在头文件中放全局变量吗¶
5 判断文本编码格式¶
5.1 utf-8 格式表示字符范围¶
Unicode/UCS-4 | bit 数 | UTF-8 | byte 数 |
---|---|---|---|
0000~007F | 0~7 | 0XXX XXXX | 1 |
0080~07FF | 8~11 | 110X XXXX 10XX XXXX | 2 |
0800~FFFF | 12~16 | 1110XXXX 10XXXXXX 10XXXXXX | 3 |
10000~1FFFFF | 17~21 | 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX | 4 |
5.2 利用 utf-8 编码特性来判断文本是否是 utf-8 编码¶
bool IsUTF8(const void* pBuffer, long size)
{
bool IsUTF8 = true;
unsigned char* start = (unsigned char*)pBuffer;
unsigned char* end = (unsigned char*)pBuffer + size;
while (start < end)
{
if (*start < 0x80) // (10000000): 值小于0x80的为ASCII字符
{
start++;
}
else if (*start < (0xC0)) // (11000000): 值介于0x80与0xC0之间的为无效UTF-8字符
{
IsUTF8 = false;
break;
}
else if (*start < (0xE0)) // (11100000): 此范围内为2字节UTF-8字符
{
if (start >= end - 1)
{
break;
}
if ((start[1] & (0xC0)) != 0x80)
{
IsUTF8 = false;
break;
}
start += 2;
}
else if (*start < (0xF0)) // (11110000): 此范围内为3字节UTF-8字符
{
if (start >= end - 2)
{
break;
}
if ((start[1] & (0xC0)) != 0x80 || (start[2] & (0xC0)) != 0x80)
{
IsUTF8 = false;
break;
}
start += 3;
}
else
{
IsUTF8 = false;
break;
}
}
return IsUTF8;
}
bool CConvertCharset::IsUTF8File(const char* pFileName)
{
FILE *f = NULL;
fopen_s(&f, pFileName, "rb");
if (NULL == f)
{
return false;
}
fseek(f, 0, SEEK_END);
long lSize = ftell(f);
fseek(f, 0, SEEK_SET); //或rewind(f);
char *pBuff = new char[lSize + 1];
memset(pBuff, 0, lSize + 1);
fread(pBuff, lSize, 1, f);
fclose(f);
bool bIsUTF8 = IsUTF8Text(pBuff, lSize);
delete []pBuff;
pBuff = NULL;
return bIsUTF8;
}
6 无拷贝类的实现¶
- 编写一个基类,将拷贝构造,拷贝复制私有化
- 类私有基类上面的类。
class noncopyable
{
protected:
noncopyable() {}
~noncopyable() {}
private:
noncopyable(const noncopyable&);
const noncopyable& operator=(const noncopyable&);
};
class A : private noncopyable
{
};