4_软件重构_二进制兼容接口设计

       上次提到了软件重构的组件化核心设计思想——将功能拆分,进行模块化,减少耦合。但是模块之间如何通讯呢?这个问题先不说,这次聊下接口的二进制兼容,主要是C++语言的。

一、二进制兼容例子

1.什么是二进制兼容(Binary Compatibility)

源代码兼容(Source Compatibility):旧代码能用新头文件重新编译就能跑。

二进制兼容(Binary Compatibility, ABI Compatibility):旧的可执行文件或旧插件,不用重新编译,只换库文件就能跑。这次明确的。

后者更严格,SDK/库升级要保证 ABI 稳定,否则客户的程序会崩溃或出现奇怪错误。

2. 破坏 ABI 兼容性的操作

在 C++ 里,以下操作会破坏二进制兼容:

(1)类布局(layout)改变

增加/删除/改变类的成员变量

修改成员变量类型(比如 int → long)

改变继承关系(多继承、虚拟继承方式)

因为对象内存布局不同,旧二进制访问偏移会错乱。重点

(2)虚函数表(vtable)改变

增加/删除虚函数

改变虚函数声明顺序

改变虚函数签名(返回值/参数不同)

改变析构函数虚拟/非虚拟属性

这会导致 vtable index 不一致,调用指向错误函数。

(3)函数签名改变

参数类型或数量改变

返回值类型改变

函数调用约定(cdecl/stdcall)改变

内联函数(inline)实现变化 → 若被编译进用户代码,就不会更新

(4)符号可见性 / 命名空间变化

改变导出符号的名字(包括 C++ 名字修饰 mangling 影响)

从 namespace A 移到 namespace B

extern "C" → 普通 C++ 函数(mangled)

(5)宏/常量/枚举大小变化

枚举底层类型改变(enum class vs 普通 enum)

sizeof(enum) 或常量值变化 → 导致旧代码逻辑不一致

(6)结构体对齐方式变化

编译器选项(#pragma pack, -fpack-struct)改变

不同编译器/平台的 ABI 差异

       总结:类的内存布局被改变,按照原来的偏移地址访问会发生未知情况。

3. 如何保证二进制兼容

(1)稳定 ABI 设计策略

使用 PIMPL(Pointer to Implementation)惯用法

公共 API 只暴露指针/句柄

内部实现隐藏在 .cpp

升级时可以自由改实现,不影响 ABI

4. Example 

不好的接口:

#pragma once class Add{public:int add(int x, int y);private:       int x_;}; #include "add.h"#include int Add::add(int x, int y){       x_ = x;    int ret = x + y;    std::cout << " x is ********" << ret << std::endl;    return ret;}

优化后的接口:

#pragma once#include class Data; // 前置声明 class Add{public:    Add();    ~Add(); public:    int getX();    int getY();    int add(int x, int y); private:    // 不透明指针    Data *pData_{nullptr};}; #include "add.h"#include class Data{public:    int x_;    int y_{6};}; Add::Add(){    pData_ = new Data();} Add::~Add(){    delete pData_;} int Add::getX(){    return pData_->x_;} int Add::getY(){    return pData_->y_;} int Add::add(int x, int y){    pData_->x_ = x;    std::cout << "x is >>  y is >>>>>" << pData_->x_ <<  pData_->y_ << std::endl;     int ret = x + y;    std::cout << "********" << ret << std::endl;    return ret;}

对私有变量进行隐藏,私有变量类使用一个指针变量进行指向,私有变量的增删不会影响class的内存布局。但是如果改变函数签名是不行的。

二、投资

       上周股市再次冲高。

       作为韭菜中的一棵,随波逐流。周五上午有那么一丢时间,达到预期,稍减仓了一些;下午1:30开会一直到3点结束,看了一眼——卖了的芯片涨了、卖了的金山办公大涨,少赚比亏了还难受…在这记录下,当股票一天的盈利达到一个月的工资时,竟然没什么感觉,只有对卖飞了的一点儿遗憾…个人判断牛市持续时间会以年为单位,个人投资也后面也需以年为单位规划,不过中间的道路会比较曲折,判断原因是觉得经济不咋样。后面估计还是抱团继续炒,散户手里大量持有的不会怎么涨,散户都赚钱了的话,那谁亏?

换个思路考虑下,即使今年股票盈利10W,对个人的生活轨迹会有较大改变么?显然是不会的。10W按照15%的盈利,本金需要67W;按照20%盈利,需要50W,按照25%盈利,需要40万;30%盈利需要34W。我觉得挺不容易。我一直没有全仓,按照银河证券的计算方式今年我的盈利是12%。我觉得挺多了。。。

之所以一直接触股票,很大一部分原因是想把它作为提前退休副业的一部分。如果后面有较为客观的收益——按2~3年为收益周期统计,每年有月薪3千的收益即可,包括银行存款的收益或是其他投资收益。

继续加油!早日退休!

诸君共勉!

计划提前退休最合适的时间是刚开始工作时,其次是现在!

欢迎关注:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值