如果不含C++模板的情况整个类中的定义是可以以二进制代码(硬编码)编译导出到obj的,而类中的定义确切指的是类中的所有成员函数它的符号命名(与成员属性无关,因为成员属性在给出声明头文件时就可以确定其内存模型了,成员属性可以重复声明/定义)
在传统C++开发中,可以采用分离式声明/定义来给到类的开发,但白易的目标还是想尽可能允许你不需要分离也能(因为维护两份代码本身就比较麻烦),
在单文件中你可以直接在VS(选中类后)用顶部导航直接定位到文件相关的一处代码,你改它(比如部分参数类型)或整个方法把它删掉都是很方便的。

而分离了的话一处改了另一处也要再改...
当然传统分离肯定也是有其不得已的时候,且听我后续的分析~
如果你希望分离那IDE里也还有比较便捷的处理手段(包括白易提供的删除当前方法/定义这一功能)
1.、Ctrl+. 这个VS自带的快速重构也能帮助你根据当前选中的声明代码去快速创建(在.cpp源文件中)定义代码
2、并且,已经有声明和定义后再去点它
VS里是以这种弹出式窗口来让你在线编辑(当然也能跳转过去了):
3、更改签名的话则是把类型两边都改了
但唯独VS没有提供方法的删除,所以白易做了它
之前在《C++工程基本开发模式》一章中说过C++对类中的方法导出时它的符号是默认具备inline特性,其实这个说法并没太大的问题,只是还要加个限定如果一个源文件没有对外(有外部extern性质的函数)进行引用的话那么类中方法压根就不能顺利参与编译而导出符号!
这里我们可以简单做一下实验:
接着我们把该源文件去掉定义仅保留后直接在main.cpp中引入

看到了吗?明明我们Person.obj都已经编译好了但就是无法找到符号?
且我们通过dumpbin.exe查看后发现也确实找不到setAge这个符号
这本质就是让在类中的方法升级转变为具备extern的外联特性。
注:在白易的模块头文件生成器中自然也可以过滤掉是外部定义的方法,只留下类中声明
但这样我们其实就恢复到了要维护两个地方的声明和定义,也不是很舒服~
实际上下面还有别的解法(但也不都是完美解):
我们试着在Person.cpp中再随便定义个全局函数(默认具备extern特性)

首先生成后发现这里链接步骤已经少了一行(构造函数可以找到了),但setAge方法依旧还是缺失的
那么我们再asd里再简单引用一下这个setAge(当然这个asd函数整体压根不会被调用,只是给到引出)
其实所有inline特性的函数默认都不具备编译到导出符号,之前C++工程基本开发模式.mht的演示,完全是说它头文件整个都引入到main.cpp中而后有main函数这个外部函数进行引用,所以它整个类中方法的符号才确实正常编译到obj中了(并且是pick any特性)
这样确实就没问题了,但假如类中方法很多的话这样搞一样累死人,并且还有致命问题private权限的你怎么引用?(当然你可以再搞友元函数),那再假如如果出现方法同名重载你怎么搞?假如函数参数本身很复杂你要一个个投入?


这里getAge也是要加,但我main.cpp那边就只用到了setAge所以这里暂且没加

不过要注意构造函数不支持virtual,所以这个还是要在外部定义
但深入研究过C++的也都知道,虚表这个东西并非是0开销(间接call),而且每个类如果都有虚表也会造就程序整体的体积增大,所以用virtual并非是导出整个类的最优解。

这样确实就把整个类导出了,但你真觉得这个就没有副作用吗?
有的,它让exe里也有了导出表,原本exe里就不该有导出表的,而DLL也就罢了(但也不一定总是导出)

那这个方案在白易模块制作中还能不能用?会污染到日后将模块引入的主程序吗?
确实,在整个VC方案中(除了传统分离式外)再也找不到导出整个类的最佳方案了,用上边的EXP本身是最简便的通用方案,但唯独的缺陷就是它生成的导出表

事实上面对这个缺陷,白易模块的制作器MakeBEC.exe把该静态库中的所有obj在二进制层面所声明要export的那些字段给抹除不就OK了吗?
是的,这样通过这种简单手术改造后,白易模块对类的支持就已经完美了!(该后期处理lib去除导出指令的方案属于免费,Pro付费版解决的还不是这种)
下面接着演示一下,白易模块中导出类



然后在主程项目中引入该白易模块

然后开始使用并编译:

生成的没有任何导出表的痕迹!完美~
但,这个方案也仅对于说要编译到lib二进制是完美的,对于要制作为源码的模块则该方案就会存在缺陷了(源码被外部主程项目引用时,其中EXP会带出来导出表被嵌入到最终的EXE中),所以要想搞成源码的类你还是单文件的.hpp来弄吧(也不需要给EXP了),单文件的话自然就是被多个编译单元引用时编译速度的问题了~(当然开了多线程编译后可能也还好)
当然还可以下面的方案进行混合编写(在cpp里include该hpp,而白易插件对cpp生成头文件时就会包含它了):


后记:在白易插件0.7+作者已通过hook链接期的VS把cpp源文件生成的obj(仅主程方面),对其进行obj内部改造(包括Release下无公开文档的LTCG版obj部分)让其主程模块在编译时精准进行去除导出表的嵌入,完美编译出该exe,不过对此属于Pro版收费项。