類屬回撥的實驗
阿新 • • 發佈:2018-12-15
前言
以前也總結過2次使用類屬回撥函式的方法。總是要借用靜態函式,很醜。
上個週末在做其他實驗時,也用到了類屬回撥.
這次找的資料中,使用類屬回撥的方式很優雅。
demo下載點
工程預覽
// @file main.cpp // @brief 對mysql操作進行封裝, 使操作mysql資料庫方便些 // @note // 實驗環境: // debian8.8 #include <stdlib.h> #include <stdio.h> #include <stdint.h> #include <string.h> #include <unistd.h> #include <signal.h> #include <string> #include <errno.h> #include "const_define.h" void init(const char* psz_log_owner_name); void uninit(); void proc_sig_term(int num); int fn_test(int argc, char** argv); class cls_test_callback { public: typedef bool (cls_test_callback::*PFN_cb_proc_2_number)( int i, int j, bool& b_process_ok); public: cls_test_callback() { m_i = 0; m_j = 0; } ~cls_test_callback() {} void set_data(int i, int j) { m_i = i; m_j = j; } bool process_2_number(PFN_cb_proc_2_number cb) { bool b_rc = false; do { if (NULL == cb) { break; } if (!(this->*cb)(m_i, m_j, b_rc)) { // call back proc say : need not to call back next break; } } while (0); return b_rc; } bool math_add(int i, int j, bool& b_process_ok) { MYLOG_D("%d + %d = %d\n", i, j, i + j); b_process_ok = true; return false; } bool math_sub(int i, int j, bool& b_process_ok) { MYLOG_D("%d - %d = %d\n", i, j, i - j); b_process_ok = true; return false; } private: int m_i; int m_j; }; int fn_test(int argc, char** argv) { bool b_rc = false; MYLOG_D(">> fn_test()\n"); cls_test_callback test_cb; do { test_cb.set_data(100, 200); test_cb.process_2_number(&cls_test_callback::math_add); test_cb.process_2_number(&cls_test_callback::math_sub); /** run result Oct 29 16:05:22 localhost test_class_callback: [MYLOG_D : main.cpp.110 : main()] : MAKE_FILE_MACRO__BIN_NAME = [test_class_callback] Oct 29 16:05:22 localhost test_class_callback: [MYLOG_D : main.cpp.84 : fn_test()] : >> fn_test() Oct 29 16:05:22 localhost test_class_callback: [MYLOG_D : main.cpp.64 : math_add()] : 100 + 200 = 300 Oct 29 16:05:22 localhost test_class_callback: [MYLOG_D : main.cpp.71 : math_sub()] : 100 - 200 = -100 Oct 29 16:05:22 localhost test_class_callback: [MYLOG_D : main.cpp.118 : main()] : THE END */ b_rc = true; } while (0); if (!b_rc) { MYLOG_D("test failed r\n"); } return 0; } int main(int argc, char** argv) { char sz_buf[MAX_MSG_LENGTH] = {'\0'}; #ifdef MAKE_FILE_MACRO__BIN_NAME sprintf(sz_buf, "%s", MAKE_FILE_MACRO__BIN_NAME); init(sz_buf); MYLOG_D("MAKE_FILE_MACRO__BIN_NAME = [%s]\n", MAKE_FILE_MACRO__BIN_NAME); #else init(NULL); #endif // #ifdef MAKE_FILE_MACRO__BIN_NAME fn_test(argc, argv); uninit(); MYLOG_D("THE END\n"); return EXIT_SUCCESS; } void uninit() { } void proc_sig_term(int num) { MYLOG_D("SIGTERM = %d, num = %d\n", SIGTERM, num); MYLOG_D("maybe can do some clean task before quit\n"); exit(1); } void init(const char* psz_log_owner_name) { int i = 0; // daemon(0, 0); // clear screen (print 25 empty line) for (i = 0; i < 25; i++) { MYLOG_D("\n"); } signal(SIGTERM, proc_sig_term); }
// @file const_define.h #if not defined(__CONST_DEFINE_H__) #define __CONST_DEFINE_H__ #include <string.h> #include <stdint.h> #include <syslog.h> #include <string> #include <list> typedef unsigned int uint; typedef unsigned short ushort; typedef unsigned long long ull; #ifndef SAFE_DELETE #define SAFE_DELETE(p) \ if (NULL != (p)) { \ delete (p); \ (p) = NULL; \ } #endif // #ifndef SAFE_DELETE #ifndef SAFE_DELETE_ARY #define SAFE_DELETE_ARY(p) \ if (NULL != (p)) { \ delete[] (p); \ (p) = NULL; \ } #endif // #ifndef SAFE_DELETE #define TITLE_LINE80 "================================================================================" #define LINE80 "--------------------------------------------------------------------------------" #if not defined(MYLOG_D) #define USE_SYSLOG #ifdef USE_SYSLOG #define MYLOG_V(fmt, ...) \ syslog(LOG_INFO, "[%s : %s.%d : %s()] : " fmt, "MYLOG_V", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); #define MYLOG_D(fmt, ...) \ syslog(LOG_INFO, "[%s : %s.%d : %s()] : " fmt, "MYLOG_D", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); #define MYLOG_I(fmt, ...) \ syslog(LOG_INFO, "[%s : %s.%d : %s()] : " fmt, "MYLOG_I", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); #define MYLOG_W(fmt, ...) \ syslog(LOG_INFO, "[%s : %s.%d : %s()] : " fmt, "MYLOG_W", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); #define MYLOG_E(fmt, ...) \ syslog(LOG_INFO, "[%s : %s.%d : %s()] : " fmt, "MYLOG_E", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); #define MYLOG_F(fmt, ...) \ syslog(LOG_INFO, "[%s : %s.%d : %s()] : " fmt, "MYLOG_F", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); #else // #ifdef USE_SYSLOG #define MYLOG_V printf #define MYLOG_D printf #define MYLOG_I printf #define MYLOG_W printf #define MYLOG_E printf #define MYLOG_F printf #endif // #ifdef USE_SYSLOG #endif // #if not defined(MYLOG_D) #define MAX_MSG_LENGTH (1024 * 4) #endif // #if not defined(__CONST_DEFINE_H__)
# ==============================================================================
# @file makefile
# ==============================================================================
# @note
# howto build project
# make BIN_NAME="bin_name_by_you_want" rebuild
# makefile code need tab key not sapce key
MY_MAKE_FILE_PATH_NAME = $(MAKEFILE_LIST)
# macro from Makefile command line
# BIN_NAME
# macro to C project
MAKE_FILE_MACRO__BIN_NAME="make_file_macro__bin_name"
# var define on Makefile
BIN = output_not_give_bin_name
IS_BUILD_TYPE_VALID = 0
ifdef BIN_NAME
IS_BUILD_TYPE_VALID = 1
BIN = $(BIN_NAME)
MAKE_FILE_MACRO__BIN_NAME=$(BIN_NAME)
else
IS_BUILD_TYPE_VALID = 0
endif
LINE80 = --------------------------------------------------------------------------------
# CC = g++ -std=c++98
CC = g++
# -Werror is "warning as error"
CFLAGS = -Wall -Werror -g
INC = -I.
LIBPATH = -L. -L/usr/lib/ -L/usr/local/lib/
ifeq (1, $(IS_BUILD_TYPE_VALID))
LIBS = -lstdc++ -pthread
else
LIBS =
endif
DEPEND_CODE_DIR = ../common/ \
DEPEND_CODE_SRC = $(shell find $(DEPEND_CODE_DIR) -name '*.cpp')
DEPEND_CODE_OBJ = $(DEPEND_CODE_SRC:.cpp=.o)
ROOT_CODE_SRC = $(shell find ./ -name '*.cpp')
ROOT_CODE_OBJ = $(ROOT_CODE_SRC:.cpp=.o)
SUB_CODE_DIR = ./empty_dir
SUB_CODE_SRC = $(shell find $(SUB_CODE_DIR) -name '*.cpp')
SUB_CODE_OBJ = $(SUB_CODE_SRC:.cpp=.o)
.PHONY: help
help:
clear
@echo "usage:"
@echo
@echo "build project by given bin name"
@echo "make BIN_NAME=\"bin_name_by_you_want\" rebuild"
@echo
.PHONY: clean
clean:
clear
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo
@echo "make clean begin"
@echo $(LINE80)
@echo "@file $(MY_MAKE_FILE_PATH_NAME)"
@echo "IS_BUILD_TYPE_VALID = $(IS_BUILD_TYPE_VALID)"
@echo "BIN = $(BIN)"
@echo $(LINE80)
rm -f $(ROOT_CODE_OBJ) $(DEPEND_CODE_OBJ) $(SUB_CODE_OBJ)
ifeq (1, $(IS_BUILD_TYPE_VALID))
rm -f ./$(BIN)
endif
@echo "make clean over"
.PHONY: all
all:$(BIN)
@echo $(LINE80)
@echo make all
chmod 777 ./$(BIN)
find . -name "$(BIN)"
$(BIN) : $(ROOT_CODE_OBJ) $(DEPEND_CODE_OBJ) $(SUB_CODE_OBJ)
$(CC) $(CFLAGS) -o [email protected] $^ $(SHLIBS) $(INC) $(LIBPATH) $(LIBS)
.cpp.o:
$(CC) -c $(CFLAGS) -DMAKE_FILE_MACRO__BIN_NAME="\"$(MAKE_FILE_MACRO__BIN_NAME)\"" $^ -o [email protected] $(INC) $(LIBPATH) $(LIBS)
.PHONY: rebuild
rebuild:
make -f $(MY_MAKE_FILE_PATH_NAME) clean
ifeq (1, $(IS_BUILD_TYPE_VALID))
@echo $(LINE80)
make -f $(MY_MAKE_FILE_PATH_NAME) all
chmod 775 ./$(BIN)
ldd ./$(BIN)
else
@echo $(LINE80)
@echo "error : Makefile command line input error, please see help"
@echo "please run => make help"
@echo $(LINE80)
endif
#!/bin/bash
# ==============================================================================
# @file build_all_project.sh
# ==============================================================================
make BIN_NAME="test_class_callback" rebuild