①简单的比较函数
#include
int countMatchElements(int* beg,int* end)
{
int result = 0;
for(;beg!=end;++beg)
{
if(*beg > 20)
++result;
}
return result;
}
int main()
{
int intArray[]= { 11,16,21,19,17,30 };
//统计大于20的元素数量
std::cout<< countMatchElements(intArray,intArray+6) <<std::endl;
return 0;
}
②加入函数指针的优化(改变:传入不同的函数)
#include
int countMatchElements(int* beg,int* end,bool(*pred)(const int&))
{
int result = 0;
for(;beg!=end;++beg)
{
if(pred(*beg))
++result;
}
return result;
}
//实际比较函数
bool isGreater20(const int &val) {return val > 20};
bool isGreater25(const int &val) {return val > 25};
bool isLess10(const int &val) {return val < 10};
int main()
{
int intArray[]= { 11,16,21,19,17,30 };
//优化后的函数(用了函数指针)
std::cout<< countMatchElements(intArray,intArray+6,isGreater20) <<std::endl;
return 0;
}
③函数模板进一步优化(改变:传入的函数参数为不同类型)
#include
template<typename T>
int countMatchElements(T* beg,T* end,bool(*pred)(const T&))
{
int result = 0;
for(;beg!=end;++beg)
{
if(pred(*beg))
++result;
}
return result;
}
//实际比较函数
bool isGreater20(const int &val) {return val > 20;}
bool isGreater25(const int &val) {return val > 25;}
bool isLess10(const int &val) {return val < 10;}
bool isTinyStr(const stdLLstring &val) {return val.size() <=3;}
int main()
{
int intArray[]= { 11,16,21,19,17,30 };
//优化后的函数(用了函数指针)
std::cout<< countMatchElements(intArray,intArray+6,isGreater20) <<std::endl;
return 0;
}
④用仿函数进一步优化(改变:传入的函数参数为不同值,之前无论是模板还是函数指针都是写死的)
#include
template<typename T,typename Pred>
int countMatchElements(T* beg,T* end,Pred pred)
{
int result = 0;
for(;beg!=end;++beg)
{
if(pred(*beg))
++result;
}
return result;
}
//仿函数
template<typename T>
struct Greater{
T mVal;//
//explicit只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示
explicit Greater(T value):mVal(value) {} //构造函数初始化mVal
bool operator() (const T& val) const { return val > mVal;}//重载函数调用运算符
};
int main()
{
int intArray[]= { 11,16,21,19,17,30 };
//阈值设置为20
Greater<int> greater20{20};//不过仿函数无法给函数指针赋值
//优化后的函数(用了函数指针)
std::cout<< countMatchElements(intArray,intArray+6,greater20) <<std::endl;
return 0;
}
⑤仿函数代码难以阅读,可以用lambda表达式改造下
#include
template<typename T,typename Pred>
int countMatchElements(T* beg,T* end,Pred pred)
{
int result = 0;
for(;beg!=end;++beg)
{
if(pred(*beg))
++result;
}
return result;
}
//仿函数
template<typename T>
struct Greater{
T mVal;//
//explicit只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示
explicit Greater(T value):mVal(value) {} //构造函数初始化mVal
bool operator() (const T& val) const { return val > mVal;}//重载函数调用运算符
};
int main()
{
int intArray[]= { 11,16,21,19,17,30 };
//阈值设置为20
//Greater greater20{20};//不过仿函数无法给函数指针赋值
auto greater20 = [](auto &val)->bool {return val>20;};
//优化后的函数(用了函数指针)
std::cout<< countMatchElements(intArray,intArray+6,greater20) <<std::endl;
return 0;
}
匈牙利命名方法
DWORD dwExStyle, //dw(DWORD, unsigned long ) 无符号整型
LPCWSTR lpClassName, // lp(Long Pointer)长指针
LPCWSTR lpWindowName, // lp(Long Pointer)长指针
DWORD dwStyle, // dw(DWORD, unsigned long ) 无符号整型
int X,
int Y, // n(Short int )短整型
int nWidth, // n(Short int )短整型
int nHeight,
HWND hWndParent, // h(handle),Wnd(Window) 窗口句柄
HMENU hMenu, // h(handle) 句柄
HINSTANCE hInstance, // h(handle) 句柄
LPVOID lpParam, // lp(Long Pointer)长指针
a 数组(Array)
b 布尔值(Boolean)
by 字节(Byte)
c 有符号字符(Char)
cb 无符号字符(Char Byte,并没有神马人用的)
cr 颜色参考值(Color Ref)
cx,cy 坐标差(长度 Short Int)
dw 双字(Double Word)
fn 函数(Function)
h Handle(句柄)
i 整形(Int)
l 长整型(Long Int)
lp 长指针(Long Pointer)
m_ 类成员(Class Member)
n 短整型(Short Int)
np 近程指针(Near Pointer)
p 指针(Pointer)
s 字符串(String)
sz 以 Null 做结尾的字符串型(String with Zero End)
w 字(Word)
#include
using namespace std;
class CCount
{
public:
CCount()
{
m_count = 1;//这里不能省略,不能直接在成员声明的时候赋值为1,如果赋值为1,档SmartPtr sp时,引用技术会错误为1;
}
void Increase()
{
m_count++;
}
void Decrease()
{
m_count;
}
int GetCount()
{
return m_count;
}
private:
int m_count = 0;
};
template<typename T>
class CSmartPtr
{
public:
CSmartPtr():
p_ptr(nullptr),p_count(nullptr){} //为了应付SmartPtr sp的情况
explicit CSmartPtr(T* ptr):
p_ptr(ptr),p_count(new CCount()){}
~CSmartPtr()
{
if (p_count)
{
p_count->Decrease();
if (0 == p_count->GetCount() )
{
delete p_ptr;
delete p_count;
p_ptr = nullptr;
p_count = nullptr;
}
}
}
//拷贝构造函数
CSmartPtr(const CSmartPtr<T>& other)
{
p_ptr = other.p_ptr;
p_count = other.p_count;
p_count->Increase();
}
//拷贝赋值运算函数
CSmartPtr<T>& operator=(const CSmartPtr<T>& other)
{
if (p_ptr == other.p_ptr)
{
return *this;
}
p_ptr = other.p_ptr;
p_count = other.p_count;
p_count->Increase();
return *this;
}
T* getPtr()
{
return p_ptr;
}
T* operator->()
{
return p_ptr;
}
T& operator*() //* 返回的是解引用的内容
{
return *p_ptr;
}
int GetCount()
{
if (!p_count) return 0;
return p_count->GetCount();
}
private:
T* p_ptr;
CCount* p_count;
};
按照容器的顺序触发回调函数
#include
#include
#include
using namespace std;
typedef std::function<void()> CallbackFunc;
std::vector<CallbackFunc> g_Callbacks;
void RegisterCallback(CallbackFunc callback)
{
g_Callbacks.push_back(callback);
}
void InvokeCallbacks()
{
for (auto& callback : g_Callbacks)
{
callback();
}
}
/
void TestFunc1()
{
std::cout<<"TestFunc1 called!" << std::endl;
}
void TestFunc2()
{
std::cout << "TestFunc2 called!" << std::endl;
}
#endif // !_FIGHTER
int main()
{
RegisterCallback(TestFunc1);
RegisterCallback(TestFunc2);
InvokeCallbacks();
return 0;
}
#include
#include
#include
using namespace std;
typedef void (*CALLBACKFUN)(std::string std, int data);
//等同于
//std::function CALLBACKFUN;
class CBase
{
private:
std:: string str_;
int data_;
static CALLBACKFUN pFunc;
public:
CBase() :str_(""), data_(0) {};
void register_callback(CALLBACKFUN fun, std::string str, int data);
void excute_callback();
};
CALLBACKFUN CBase::pFunc = nullptr;
void CBase::register_callback(CALLBACKFUN fun,
std::string str, int data)
{
pFunc = fun;
str_ = str;
data_ = data;
}
void CBase::excute_callback()
{
CBase::pFunc(str_, data_);
}
/*
上层回调注册
*/
void func_1(std::string str, int data)
{
std::cout << "this is func_1 callback function" << str << "..." << data << std::endl;
}
void func_2(std::string str, int data)
{
std::cout << "this is func_2 callback function" << str << "..." << data << std::endl;
}
int main()
{
CBase c_base;
c_base.register_callback(func_1, "lyy", 6);
c_base.excute_callback();
c_base.register_callback(func_2, "klx", 8);
c_base.excute_callback();
return 0;
}
①CFunc.h
#ifndef __FIGHTER__
#define __FIGHTER__
#include
#include
#include
#include
using namespace std;
template<typename T>
class CRegister
{
public:
void RegisterFunc(T* obj)
{
m_RegisterVec.push_back(obj);
}
void Execute()
{
for (auto it = m_RegisterVec.begin(); it != m_RegisterVec.end(); ++it)
{
(*it)->DoOperation();
}
}
private:
std::vector<T*> m_RegisterVec;
};
class CDoFunc
{
public:
virtual void DoOperation() = 0;
};
class CFunc1 :public CDoFunc
{
public:
void DoOperation()
{
std::cout << "do test1" << std::endl;
}
};
class CFunc2 :public CDoFunc
{
public:
void DoOperation()
{
std::cout << "do test2" << std::endl;
}
};
#endif // !_FIGHTER
②main函数
#include
#include "Fighter.h"
int main()
{
CRegister<CDoFunc> mRegister;
CFunc1* test_1 = new CFunc1();
CFunc2* test_2 = new CFunc2();
mRegister.RegisterFunc(test_1);
mRegister.RegisterFunc(test_2);
mRegister.Execute();
return 0;
}
#include
#include
#include
#include
using namespace std;
typedef void (*CALLBACKFUN)(int data);
//等同于
//std::function CALLBACKFUN;
class CRegisterMgr
{
private:
std::map<int, CALLBACKFUN> mRegisterMap;
public:
void register_callback(CALLBACKFUN fun, int data);
void excute_callback(int excuteNum);
};
void CRegisterMgr::register_callback(CALLBACKFUN fun, int data)
{
auto it = mRegisterMap.find(data);
mRegisterMap[data] = fun;
}
void CRegisterMgr::excute_callback(int excuteNum)
{
auto it = mRegisterMap.find(excuteNum);
if (it == mRegisterMap.end())
return;
(it->second)(excuteNum);
}
/*
上层回调注册
*/
void func_1( int data)
{
std::cout << "this is func_1 callback function" << "..." << data << std::endl;
}
void func_2( int data)
{
std::cout << "this is func_2 callback function" << "..." << data << std::endl;
}
int main()
{
CRegisterMgr c_base;
c_base.register_callback(func_1, 6);
c_base.excute_callback(6);
c_base.register_callback(func_2, 8);
c_base.excute_callback(8);
return 0;
}
做法:析构函数设置为私有
原因:C++是静态绑定语言,编译器管理栈上对象的生命周期,在为类分配栈空间时,会先检查类的析构函数的访问性。若析构函数不可访问,则不能在栈上创建函数
方法:将new和delete重载为私有
原因:在堆上生成对象,使用new关键词操作,其过程分为两阶段。第一阶段:用new在堆上寻找可用内存,分配给对象;第二阶段:调用析构函数生成对象。new为私有,第一阶段就无法完成
1)指针常量
int *const p1
p2 = &a; (X)
*p2 = a; (✔)
2)常量指针
int const* p2
p2 = &a; (✔)
*p2 = a; (X)
1、堆内存泄露
2、系统资源泄露(bitmap、handle、socket等)
3、没有将基类的析构函数定义为虚函数
4、在释放对象数组时没有使用delete[]而是使用了delete
5、缺少拷贝构造函数
Count C1(C2)
①new和delete是操作符,可以被重载;malloc和free是C语言的库函数,不能被重载
②malloc需要提供分配内存的大小
③malloc返回的是void*指针;而new直接就返回了对应类型的指针
④new和delete分别调用构造和析构函数,而malloc和free只申请和释放内存。
备注:delete和free只是告诉操作系统,这一块内存被释放了,可以用作其他用途。

1)散列法
2)再散列法
3)线性列表法
extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般之包括函数名。
①要用std::ref传递引用类型变量

②记录用类的函数作为线程执行函数(奇怪的用法所以记录下)

③用友元函数访问类的私有函数作为线程执行函数

①lock_guard使用讲解

代码举例:

②std::unique_lock使用解释
延迟阻塞使用案例:

延迟2秒,拿不到锁就不进入循环:

③unique_lock的构造函数分类讲解

代码:



#include
#include
#include
#include
//#include "Fighter.h"
using namespace std;
#include
#include
#include
#include
std::mutex g_mutex;
std::condition_variable g_cv;
std::queue<int> g_que;
void producer()
{
for (int i = 0;i < 10;++i)
{
std::unique_lock<std::mutex> lock(g_mutex);
g_que.push(i);
g_cv.notify_one();
std::cout << "queue push value:" << i << std::endl;
}
}
void consumer()
{
while (1)
{
std::unique_lock<std::mutex> lock(g_mutex);
bool bEmpty = g_que.empty();
g_cv.wait(lock, []() {return !g_que.empty(); });
int value = g_que.front();
g_que.pop();
std::cout << " pop value:" << value << std::endl;
}
}
int main()
{
std::thread t1(producer);
std::thread t2(consumer);
t1.join();
t2.join();
return 0;
}