为何LLVM libc++中__shared_weak_count部分成员函数放入动态库?
你观察到的libc++中__shared_weak_count成员函数的分布情况确实是有意为之:
// in libcxx/src/memory.cpp
__shared_weak_count::~__shared_weak_count();
void __shared_weak_count::__release_weak() noexcept;// in libcxx/include/__memory/shared_ptr.h
__shared_weak_count::__shared_weak_count();
long __shared_weak_count::use_count();
核心原因可以归纳为以下几点:
实现类型擦除与封装内部细节
__shared_weak_count是shared_ptr和weak_ptr引用计数体系的基类,它的子类(比如__shared_count)会持有用户自定义的删除器、分配器等类型。如果把析构、__release_weak这类需要触发子类逻辑的函数放在头文件,就必须暴露这些子类的具体定义,这不仅会造成头文件循环依赖,还破坏了标准库的封装性——这些内部类型本就不需要让用户感知。将实现移到源文件后,头文件只需保留基类的接口声明,就能完美隐藏底层的具体类型。降低头文件耦合,优化编译效率
留在头文件的函数(比如默认构造、use_count())逻辑简单,通常会被标记为inline,编译器可以直接在调用处展开,提升调用效率。而__release_weak()这类函数需要处理引用计数归零后的资源清理逻辑——比如调用用户删除器、销毁控制块,这依赖大量内部实现细节。把它们放进源文件,就能避免将这些复杂依赖塞进头文件,减少用户代码的编译依赖链,缩短整体编译时间。遵循虚函数实现的工程规范
__shared_weak_count是包含虚函数的多态基类,这类函数的具体实现通常会放在源文件中。一方面,虚函数的调用依赖虚表,将实现集中在一个编译单元能确保虚表只生成一次,避免链接时的重复定义问题;另一方面,接口与实现分离也是C++多态类的常规设计方式,能让代码结构更清晰。
内容的提问来源于stack exchange,提问作者liginity

