《深入浅出MFC》2/e第二版对这些部份都有很深入的探讨,把MFC 里的一些机制直接trace code 加以说明。 xv News / BBS 论坛(CompBook and/or programming) 我想请问以下宏的意义及其使用时机和作用: DECLARE_DYNCREATE, DECLARE_DYNAMIC, IMPLEMENT_DYNAMIC, IMPLEMENT_DYNCREATE, DECLA RE_MESSAGE_MAP 许多朋友曾经与我讨论过,对于MFC 这类application framework,应该挖掘其内部机制到什 么程度?探究源代码,岂不有违「黑盒子」初衷?但是,没有办法,他们也同意,不把那些 奇奇怪怪的宏和指令搞清楚,只能生产出玩具来。对付MFC 内部机制,态度不必像对付 MFC 类别一样;你只需好好走过那么一回,有个印象,足矣。至于庞大繁复的整个application framework 技术的 顶之感。 第四篇【深入MFC 程序设计】介绍各式各样MFC 技术。「只知其然不知其所以然」 的不良副作用,在程序设计的企图进一步开展之后,愈来愈严重,最终会行不得也!那 些最困扰我们的MFC 宏、MFC 常数定义,不得一窥堂奥的MFC 黑箱操作,在本 篇陆续曝光。本篇将使您高喊:Eureka! 阿基米德在洗澡时发现浮力原理,高兴得来不及穿上裤子,跑到街上大喊:Eureka(我 找到了)。0 码力 | 1009 页 | 11.08 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 11 现代 CMake 进阶指南`-O3 -DNDEBUG` 3. MinSizeRel: `-Os -DNDEBUG` 4. RelWithDebInfo: `-O2 -g -DNDEBUG` • 此外,注意定义了 NDEBUG 宏会使 assert 被去除掉。 小技巧:设定一个变量的默认值 如何让 CMAKE_BUILD_TYPE 在用户没有指定的时候为 Release ,指 定的时候保持用户指定的值不变呢。 就是说 CMake Blosc::blosc ,那这个库也会自动链接到 main 上,无需调用者手动 添加。 比如 spdlog 的 spdlog-config.cmake 就会定义 SPDLOG_NOT_HEADER_ONLY 这个宏为 PUBLIC 。 从而实现直接 #include时候是纯头文件,而 find_package(spdlog REQUIRED) 时却 变成预编译链接库的版本。(嗯,其实不是 找不到会把 TBB_FOUND 设为 FALSE , TBB_DIR 为空。 这里我们在找到 TBB 时定义 WITH_TBB 宏,稍后 .cpp 里就可以根据这个判断。 如果找不到 TBB 可以 fallback 到保守的实现。 这样在 .cpp 里可以判断 WITH_TBB 宏,找不到 TBB 时退化到串行 for 循环 也可以用 TARGET 判断是否存在 TBB::tbb 这个伪对象,实现同样效果 0 码力 | 166 页 | 6.54 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - Zeno 中的现代 C++ 最佳实践 函数? • 可以定义一个宏 IOBJECT_DEFINE_CLONE ,其内容是 clone 的实现。这里我们用 std::decay_t快速获取了 this 指针所指向的类型,也就是当前所在类的类型 。 • 宏的缺点是他不遵守命名空间的规则,宏的名 字是全局可见的,不符合 C++ 的高大尚封装思 想。 • 宏: IOBJECT_DEFINE_CLONE 会在第一次进入的时候初始化。因为第一 次调用是在 defCat 中,从而保证是在所 有 emplace 之前就初始化过,因此不会 有 segfault 的问题了! 函数表结合工厂模式 Zeno 中定义节点的宏 • 在 Zeno 中每个节点还额外有一个 Descriptor 的信息,因此遵循以下格式: • ZENO_DEFNODE(ClassName)({... 0 码力 | 54 页 | 3.94 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 01 学 C++ 从 CMake 学起内的文件名 hello.h 的内容插入到记号所在的位置,这样不就只用编辑 hello.h 一次了嘛 ~ • 后来,这个编译前替换的步骤逐渐变成编译器的了一部分,称为预处理阶段, #define 定 义的宏也是这个阶段处理的。 • 此外,在实现的文件 hello.cpp 中导入声明的文件 hello.h 是个好习惯,可以保证当 hello.cpp 被修改时,比如改成 hello(int) ,编译器能够发现 # 添加要链接的库 • target_add_definitions(myapp PUBLIC MY_MACRO=1) # 添加一个宏定义 • target_add_definitions(myapp PUBLIC -DMY_MACRO=1) # 与 MY_MACRO=1 等价 • target_compile_options(myapp link_directories(/opt/cuda) # 添加库文件的搜索路径 • add_definitions(MY_MACRO=1) # 添加一个宏定义 • add_compile_options(-fopenmp) # 添加编译器命令行选项 第三方库 - 作为纯头文件引入 • 有时候我们不满足于 C++ 标准库的功能,难免会用到一些第三方库。0 码力 | 32 页 | 11.40 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 08 CUDA 开启的 GPU 编程编译器生成 GPU 指令码。最后再链接成同一个文件 ,看起来好像只编译了一次一样,实际上你的代码会被预处理很 多次。 • 他在 GPU 编译模式下会定义 __CUDA_ARCH__ 这个宏,利用 #ifdef 判断该宏是否定义,就可以判断当前是否处于 GPU 模式 ,从而实现一个函数针对 GPU 和 CPU 生成两份源码级不同的 代码。 __CUDA_ARCH__ 是个版本号 • 其实 __CUDA_ARCH__ .h • 把他和 helper_string.h 一起拷到头文件目录里,然后改一 下 CMakeLists.txt 让他包含这个头文件目录。 • 他定义了 checkCudaErrors 这个宏,使用时只需: • checkCudaErrors(cudaDeviceSynchronize()) • 即可自动帮你检查错误代码并打印在终端,然后退出。还会 报告出错所在的行号,函数名等,很方便。0 码力 | 142 页 | 13.52 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 16 现代 CMake 模块化项目管理指南里写一些你常用的函数,宏,变量等。 十三、你知道吗? CMake 也有 include 功能 • 和 C/C++ 的 #include 一样, CMake 也有一个 include 命令。 • 你写 include(XXX) ,则他会在 CMAKE_MODULE_PATH 这个列表 中的所有路径下查找 XXX.cmake 这个文件。 • 这样你可以在 XXX.cmake 里写一些你常用的函数,宏,变量等。0 码力 | 56 页 | 6.87 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 12 从计算机组成原理看 C 语言指针可以用更安全的 func(std::optionalpars) 来替代。 NULL 的定义为什么是这样的? • 如果你看过标准库的头文件内容,会看到 NULL 的 本质无非是一个宏。那为什么要这样定义呢? • 可见他在 C++ 中会直接定义为常数 0 ,而 C 语言 中却定义为 ((void*)0) ,为什么会区别对待? • 这是因为 C++ 规定 0 可以代表空指针,为什么要 0 码力 | 128 页 | 2.95 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 07 深入浅出访存优化后面不加 REQUIRED ,这样找不到就不会报错。 • 然后用 TARGET TBB::tbb 判断是否找到了 tbb , 如果没找到抛出警告,但是不影响使用。如果找到就 链接上,并定义宏 WITH_TBB 让源文件判断。 • 然后在 .cpp 文件里写 #ifdef WITH_TBB 包围住需 要用到 tbb 的部分,这样即使没有 tbb 的同学也能 正常编译其他没有 tbb 的0 码力 | 147 页 | 18.88 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 15 C++ 系列课:字符与字符串在调用英文版 Windows 的 LoadLibraryA 系列函数需要用: const char * , UTF-8 编码的字符串。 • Windows 还定义了 LoadLibrary 这个宏,还有 TCHAR 这个类型别名(编 译时可以自动变成 wchar_t 或者 char ),方便程序员自动切换于两个版本之 间。 • Linux 则没有分两个版本,会根据环境变量 LANG 和 LC_ALL0 码力 | 162 页 | 40.20 MB | 1 年前3
共 9 条
- 1













