跳转至

实用处理技巧

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 无拷贝类的实现

  1. 编写一个基类,将拷贝构造,拷贝复制私有化
  2. 类私有基类上面的类。
class noncopyable
{
protected:
  noncopyable() {}
  ~noncopyable() {}
private:
  noncopyable(const noncopyable&);
  const noncopyable& operator=(const noncopyable&);
};
class A : private noncopyable
{

};