从静态库公开一个类

Exposing a class from Static Library

本文关键字:一个 静态      更新时间:2023-10-16

我正在开发一个解析器库,我在其中解析数据并将其存储在不同的数据结构中。库的设计是这样的,它将有一个数据提供者、解析器和数据存储类。数据存储是DataProvider类的成员。使用者需要调用DataProvider中的函数来解析文件并从库中检索数据。

现在,如果我公开DataProvider类,那么我还需要公开DataStore类,它将实现细节提供给消费者。公开DataProvider类的函数的另一种方法是什么?我应该公开函数,如LoadFile, GetRecords,并在cpp内全局创建DataProvider对象吗?

如果用户不需要直接使用DataStore,最好不要将其暴露。您可以通过创建一个"接口"来实现这一点——只有公共纯虚函数的抽象DataProvider。在内部,有一个DataProviderImp,它将继承DataProvider,并包含所有必需的定义和成员,它们是实际实现的一部分。

让用户只处理抽象类。这样,您只需将最小的依赖项拖拽到您的API中。

首先尽量减少需要在头文件中公开的信息,因此在可能的地方使用前向声明、引用和指针(因此只需要前向声明),并尝试使用PIMPL习惯用法来隐藏实现。

接下来,您可以构建另一个类,它是系统的外观,它封装了函数的入口点,并使用间接方法访问包含的元素(例如可从外部访问的数据元素),例如句柄和索引。

如果担心外部用户可能会创建自己的DataStore对象,在DataProvider的上下文中使用它们,并且他们抱怨您的库无法工作,那么有一个简单的解决方案和一些不那么简单的解决方案。

简单的解决方案:说明DataProvider是库的外部接口。这是c++标准库和Boost中采用的解决方案。std::map的接口是头文件<map>。该头文件#includes的实现文件,以及<map>及其附属头文件创建的基础数据类型都与您无关。您应该只使用std::map公共接口。使用内部数据类型,您就进入了未定义行为的世界。像// The class DataStore is for internal use only. Use it and you will be fired.这样的评论是相当强大的威慑。

一个不依赖于上面的解决方案:通过在DataProvider中定义这些子类(例如,你将有DataProvider::DataStore类)并使这些类定义私有/保护DataProvider来隔离这些子类。另一种方法是将DataStore中的所有内容设置为private/protected,并将DataProvider设置为好友类。

由于您正在交付静态库和头文件,因此无论您多么努力地将其隔离,总会有一些令人讨厌的黑客手段来获取您的底层数据和方法。在某些情况下,"This仅供内部使用。把你的脏手拿开!