【C++】常用编码及经验整理

文章目录
  1. 1. 睡眠
  2. 2. 随机字符串
  3. 3. 随机数
  4. 4. 临时禁用编译告警
  5. 5. C 开发宏整理
    1. 5.1. 文件读写标志
    2. 5.2. 申请释放内存
    3. 5.3. 用于debug的宏
    4. 5.4. windows获取nt导出函数的宏
  6. 6. C++17
  7. 7. 修改 cout 文本颜色
  8. 8. 单例模板
  9. 9. KMP查找算法
  10. 10. 通用单例模式父类

概述:C++开发过程中遇到的常用代码段和经验整理

[toc]

睡眠

1
2
3
4
5
6
头文件定义:
#include <thread>
std::this_thread::sleep_for(std::chrono::milliseconds(1000));//睡眠1000毫秒(1秒)
等同:
std::chrono::milliseconds dura(1000);
std::this_thread::sleep_for(dura);

随机字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
std::string SPString::RandomString(int length)
{
std::string chars{ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" };
std::random_device rd;
std::mt19937 generator(rd());
std::string output;

output.reserve(length);

int len_chars = chars.length();

while (length > 0)
{
auto randNumb = generator();
while (randNumb > len_chars && length--)
{
output.push_back(chars[randNumb % len_chars]);
randNumb /= len_chars;
}
}
return output;
}

随机数

1
2
3
4
5
6
7
#include <random>

// 生成随机数
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 999);
int nId = dis(gen);

临时禁用编译告警

1
2
3
4
#pragma warning(push)
#pragma warning(disable:4305)
pCandidate=(VOID PTR_T PTR_T)ModuleSectionInfo.pBase;
#pragma warning(pop)

C 开发宏整理

文件读写标志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
* NOTE: this is also used for opening text files.
* WIN32 treats Control-Z as EOF in files opened in text mode.
* Therefore, we open files in binary mode on Win32 so we can read
* literal control-Z. The other affect is that we see CRLF, but
* that is OK because we can already handle those cleanly.
*/
#if defined(WIN32) || defined(__CYGWIN__)
#define PG_BINARY O_BINARY
#define PG_BINARY_A "ab"
#define PG_BINARY_R "rb"
#define PG_BINARY_W "wb"
#else
#define PG_BINARY 0
#define PG_BINARY_A "a"
#define PG_BINARY_R "r"
#define PG_BINARY_W "w"
#endif

申请释放内存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#ifdef _DEBUG
//
// DEBUG
//
#ifndef DBG_NEW
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
#define new DBG_NEW
#endif

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

#define OS_FREE(pMem) free(pMem)
#define OS_ALLOC(Size) calloc(Size,1);
#define OS_DEBUG(...) _cprintf(__VA_ARGS__)
#define DEBUG_BREAK() __debugbreak()
#else
//
// RELEASE
//
#define OS_FREE(pMem) HeapFree(GetProcessHeap(), 0, pMem)
#define OS_ALLOC(Size) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size)
#define OS_DEBUG(...) _cprintf(__VA_ARGS__)
#define DEBUG_BREAK()
#endif // _DEBUG

用于debug的宏

需要自己实现 AutoDebugTrace 部分,也可直接替换 outputdebug

1
2
#define DBUG_TRACE \
const AutoDebugTrace _db_trace(DBUG_PRETTY_FUNCTION, __FILE__, __LINE__)

windows获取nt导出函数的宏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#ifndef _MANAGED
#if _MSC_VER >= 1200
#pragma warning(push)
#pragma warning(disable:4255) // () treated as (void)
#endif
#ifndef _MAC
#ifdef _WIN64
typedef INT_PTR (FAR WINAPI *FARPROC)();
typedef INT_PTR (NEAR WINAPI *NEARPROC)();
typedef INT_PTR (WINAPI *PROC)();
#else
typedef int (FAR WINAPI *FARPROC)();
typedef int (NEAR WINAPI *NEARPROC)();
typedef int (WINAPI *PROC)();
#endif // _WIN64
#else
typedef int (CALLBACK *FARPROC)();
typedef int (CALLBACK *NEARPROC)();
typedef int (CALLBACK *PROC)();
#endif
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#else
typedef INT_PTR (WINAPI *FARPROC)(void);
typedef INT_PTR (WINAPI *NEARPROC)(void);
typedef INT_PTR (WINAPI *PROC)(void);
#endif

#define DEFINE_NTDLL(x) _ ## x f ## x = (_ ## x)GetProcAddressNT(#x)

FARPROC GetProcAddressNT(LPCSTR lpName)
{
return GetProcAddress(GetModuleHandleW(L"ntdll"), lpName);
}

C++17

[[fallthrough]] 用法,在 switch case中不中断继续执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
switch (DoTrace(cs)) {
case ENABLE_TRACE:
cs->framep->level |= TRACE_ON;
if (!TRACING) break;
[[fallthrough]]; // 不跳出 switch,继续下一个case
case DO_TRACE:
if (TRACING) {
if (!cs->locked) native_mutex_lock(&THR_LOCK_dbug);
DoPrefix(cs, _line_);
Indent(cs, cs->level);
(void)fprintf(cs->stack->out_file, ">%.*s\n", cs->func_len, cs->func);
DbugFlush(cs); /* This does a unlock */
}
break;
case DISABLE_TRACE:
cs->framep->level &= ~TRACE_ON;
[[fallthrough]];
case DONT_TRACE:
break;
}

修改 cout 文本颜色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//
// main.cpp
// ColoredHelloWorld
//
// Created by obaby on 14-2-27.
// Copyright (c) 2014年 mars. All rights reserved.
//

#include <iostream>

//the following are UBUNTU/LINUX ONLY terminal color codes.
#define RESET "\033[0m"
#define BLACK "\033[30m" /* Black */
#define RED "\033[31m" /* Red */
#define GREEN "\033[32m" /* Green */
#define YELLOW "\033[33m" /* Yellow */
#define BLUE "\033[34m" /* Blue */
#define MAGENTA "\033[35m" /* Magenta */
#define CYAN "\033[36m" /* Cyan */
#define WHITE "\033[37m" /* White */
#define BOLDBLACK "\033[1m\033[30m" /* Bold Black */
#define BOLDRED "\033[1m\033[31m" /* Bold Red */
#define BOLDGREEN "\033[1m\033[32m" /* Bold Green */
#define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */
#define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */
#define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */
#define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */
#define BOLDWHITE "\033[1m\033[37m" /* Bold White */

int main(int argc, const char * argv[])
{

// insert code here...
std::cout< <RED <<"Hello, World! in RED\n";
std::cout<<GREEN <<"Hello, World! in GREEN\n";
std::cout<<YELLOW <<"Hello, World! in YELLOW\n";
std::cout<<BLUE <<"Hello, World! in BLUE\n";
std::cout<<MAGENTA <<"Hello, World! in MAGENTA\n";
std::cout<<CYAN <<"Hello, World! in CYAN\n";
std::cout<<WHITE <<"Hello, World! in WHITE\n";
std::cout<<BOLDRED <<"Hello, World! in BOLDRED\n";
std::cout<<BOLDCYAN <<"Hello, World! in BOLDCYAN\n";
return 0;
}

在 windows 中也可以使用SetConsoleTextAttribute 接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// ColordCout.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <windows .h>

using namespace std;

void SetColor(unsigned short forecolor =4 ,unsigned short backgroudcolor =0)
{
HANDLE hCon =GetStdHandle(STD_OUTPUT_HANDLE); //获取缓冲区句柄
SetConsoleTextAttribute(hCon,forecolor|backgroudcolor); //设置文本及背景色
}

int _tmain(int argc, _TCHAR* argv[])
{
SetColor(40,30);
std::cout < <"Colored hello world for windows!\n";
SetColor(120,20);
std::cout <<"Colored hello world for windows!\n";
SetColor(10,50);
std::cout <<"Colored hello world for windows!\n";
return 0;
}

单例模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template<typename T>
class Singleton {
protected:
Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;

public:
static T& getInstance() {
static T instance;
return instance;
}
};

// 使用方式
class MyClass : public Singleton<MyClass> {
friend class Singleton<MyClass>;
private:
MyClass() {} // 私有构造函数
// 其他成员...
};

KMP查找算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
int KMPSearch(const void* src, size_t srcLen, const void* pat, size_t patLen)
{
if (patLen == 0)
{
return 0;
}

if (srcLen < patLen)
{
return -1;
}

auto GetNext = [](const void* pat, size_t patLen, int* next)
{
size_t i = 1;
size_t j = 0;
const char* ptr = (const char*)pat;

next[0] = 0;

while (i < patLen)
{
if (ptr[j] == ptr[i])
{
next[i] = j + 1;
i++;
j++;
}
else if (j != 0)
{
j = next[j - 1];
}
else
{
i++;
}
}
};

std::unique_ptr<int[]> next(new(std::nothrow) int[patLen] {0});
if (next == nullptr)
{
return -1;
}
GetNext(pat, patLen, next.get());

size_t i = 0;
size_t j = 0;
const char* ptrSrc = (const char*)src;
const char* ptrPat = (const char*)pat;
while (i < srcLen && j < patLen)
{
if (ptrSrc[i] == ptrPat[j])
{
i++;
j++;
}
else if (j != 0)
{
j = next[j - 1];
}
else
{
i++;
}
}

if (j == patLen)
{
return i - patLen;
}

return -1;
}

通用单例模式父类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#pragma once

#include "noncopymoveable.h"
#if _MSC_VER >1700
#include <mutex>
template <typename T>
class LL_singleton:public noncopymoveable
{
public:
inline static T & GetInstance()
{

std::call_once(s_oc, [&] {
auto& _instance = _GetInstance();
try
{
_instance.RunOnce();
}
catch (...)
{

}

});


return _GetInstance();
}
#pragma message( __FILE__ "(" _CRT_STRINGIZE(__LINE__) ") RunOnce轻量级初始化,不建议做复杂的操作 ")
virtual void RunOnce() {};//线程安全;
protected:
LL_singleton() {}; //单例就禁止再外部构造了;
private:
inline static T &_GetInstance()
{
static T s_instance;
return s_instance;
}
private:
static std::once_flag s_oc;
};q
template<class T>
__declspec(selectany)
std::once_flag LL_singleton<T>::s_oc;
#else
#define LL_singleton LL_singleton_unsafe
#endif



template <typename T>
class LL_singleton_unsafe :public noncopymoveable
{
public:
inline static T & GetInstance()
{
static T s_instance;
return s_instance;
}
protected:
LL_singleton_unsafe() {}; //单例就禁止再外部构造了;

};