前言:
笔者以前只学过C语言,没有学过C++,在新项目中用到C++做开发,因此需要快速学习C++。
注:
1.编译环境:g++.exe (x86_64-posix-seh-rev3, Built by MinGW-W64 project) 11.2.0
2.本篇使用的BaseClass代表基类,使用的DerivedClass代表衍生类。
无类的C语言风格回调函数使用
#include <iostream>
#include <string>
typedef void (*CallbackFunc)(std::string, unsigned int);
typedef struct {
unsigned int id;
CallbackFunc callbackFunc;
} CallbackIdInfomation_t;
void run_1(std::string name, unsigned int id)
{
printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
}
void run_2(std::string name, unsigned int id)
{
printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
}
void run(std::string name, unsigned int id)
{
const CallbackIdInfomation_t callbackIdInfolist[] = {
{1, run_1},
{2, run_2},
{3, nullptr},
};
const int callbackIdInfolistSize = sizeof(callbackIdInfolist) / sizeof(callbackIdInfolist[0]);
for (int index = 0; index < callbackIdInfolistSize; index++) {
if (callbackIdInfolist[index].id == id) {
if (callbackIdInfolist[index].callbackFunc != nullptr) {
callbackIdInfolist[index].callbackFunc(name, id);
} else {
printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
}
break;
}
}
}
int main(int argc, char *argv[])
{
run("argv_1", 1);
run("argv_2", 2);
run("argv_3", 3);
run("argv_4", 4);
return 0;
}
总结:
没有使用类的情况下,使用C语言风格的回调函数可以正常编译/运行。
有类的C语言风格回调函数使用
#include <iostream>
#include <string>
typedef void (*CallbackFunc)(std::string, unsigned int);
typedef struct {
unsigned int id;
CallbackFunc callbackFunc;
} CallbackIdInfomation_t;
class BaseClass {
public:
virtual void run(std::string name, unsigned int id) {}
};
class DerivedClass: public BaseClass {
public:
void run(std::string name, unsigned int id) override;
void runDerived(std::string name, unsigned int id);
void run_1(std::string name, unsigned int id) {
printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
}
void run_2(std::string name, unsigned int id) {
printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
}
};
void DerivedClass::run(std::string name, unsigned int id)
{
runDerived(name, id);
}
void DerivedClass::runDerived(std::string name, unsigned int id)
{
const CallbackIdInfomation_t callbackIdInfolist[] = {
// {1, DerivedClass::run_1}, // 编译报错
// {2, DerivedClass::run_2}, // 编译报错
{3, nullptr},
};
const int callbackIdInfolistSize = sizeof(callbackIdInfolist) / sizeof(callbackIdInfolist[0]);
for (int index = 0; index < callbackIdInfolistSize; index++) {
if (callbackIdInfolist[index].id == id) {
if (callbackIdInfolist[index].callbackFunc != nullptr) {
callbackIdInfolist[index].callbackFunc(name, id);
} else {
printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
}
break;
}
}
}
int main(int argc, char *argv[])
{
BaseClass* baseExample = new DerivedClass;
baseExample->run("argv_1", 1);
baseExample->run("argv_2", 2);
baseExample->run("argv_3", 3);
baseExample->run("argv_4", 4);
delete baseExample;
return 0;
}
总结:
有使用类的情况下,使用C语言风格的回调函数不可以正常编译/运行。
C++风格的回调函数使用
#include <iostream>
#include <string>
#include <functional>
typedef std::function<void(std::string, unsigned int)> CallbackFunc;
typedef struct {
unsigned int id;
CallbackFunc callbackFunc;
} CallbackIdInfomation_t;
class BaseClass {
public:
virtual void run(std::string name, unsigned int id) {}
};
class DerivedClass: public BaseClass {
public:
void run(std::string name, unsigned int id) override;
void runDerived(std::string name, unsigned int id);
void run_1(std::string name, unsigned int id) {
printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
}
void run_2(std::string name, unsigned int id) {
printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
}
};
void DerivedClass::run(std::string name, unsigned int id)
{
runDerived(name, id);
}
void DerivedClass::runDerived(std::string name, unsigned int id)
{
const CallbackIdInfomation_t callbackIdInfolist[] = {
{1, [this](std::string lamdaName, unsigned int lamdaId) { run_1(lamdaName, lamdaId); }},
{2, [this](std::string lamdaName, unsigned int lamdaId) { run_2(lamdaName, lamdaId); }},
{3, nullptr},
};
const int callbackIdInfolistSize = sizeof(callbackIdInfolist) / sizeof(callbackIdInfolist[0]);
for (int index = 0; index < callbackIdInfolistSize; index++) {
if (callbackIdInfolist[index].id == id) {
if (callbackIdInfolist[index].callbackFunc != nullptr) {
callbackIdInfolist[index].callbackFunc(name, id);
} else {
printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
}
break;
}
}
}
int main(int argc, char *argv[])
{
BaseClass* baseExample = new DerivedClass;
baseExample->run("argv_1", 1);
baseExample->run("argv_2", 2);
baseExample->run("argv_3", 3);
baseExample->run("argv_4", 4);
delete baseExample;
return 0;
}
总结:
有使用类的情况下,需要使用STL的function模版 + lamda表达式,才可以正常编译/运行。