我最近决定将我的一些函数导出到静态库(.lib)。我还决定不将完整的头文件提供给用户。我将私有和受保护的变量及方法排除在外,因为最终用户不应使用它们,也不必为Class声明包括其他标头。
出乎意料的是,我在创建导出到静态库的类的实例时遇到堆损坏错误。
这是我的原始头文件:
// Original Header File
class CODBCHelper
{
public:
CODBCHelper();
virtual ~CODBCHelper();
public:
std::vector<UserData> getUserInformation();
private:
SQLHENV m_henv;
SQLHDBC m_hdbc;
SQLHSTMT m_hstmt;
};
然后,我决定删除私有变量,以便.lib的用户不会滥用它们,也不必包括不必要的SQL Header文件:
// Minimized Header File
class CODBCHelper
{
public:
CODBCHelper();
virtual ~CODBCHelper();
public:
std::vector<UserData> getUserInformation();
};
我注意到
sizeof
操作根据调用位置返回不同的值。在.lib中调用:
int size = sizeof(CODBCHelper);
// size is 12
在链接项目中调用:
int size = sizeof(CODBCHelper);
// size is 1
在我的链接项目中执行以下代码会导致堆损坏(可能是由于错误的大小计算而导致的):
CODBCHelper* helper = new CODBCHelper;
做类似的事情
class CODBCHelper
{
[...]
private:
char padding[12];
}
可以解决问题,但是我认为它的行为非常糟糕,根本无法维护。
那么,有什么方法可以告诉编译器实际的对象(来自链接库)的大小是多少?还是有任何简单的方法可以将声明隐藏在用户不需要的头文件中?
最佳答案
我看不到“隐藏不重要的成员”如何将其从类定义中删除。
我想,您想从代码中消除不必要的依赖。这是一个很好的技术-它减少了编译时间,使您的代码在不同版本之间的可移植性更高。
事实是,您完全改变了班级。如果设计为具有三个私人成员:
SQLHENV m_henv;
SQLHDBC m_hdbc;
SQLHSTMT m_hstmt;
您不能只删除它们。这不是“隐藏实现细节”的含义。
还是有任何简单的方法可以将声明隐藏在用户不需要的头文件中?
您要使用PIMPL Idiom:
//Minimized header file
class CODBCHelper
{
public:
CODBCHelper();
virtual ~CODBCHelper();
public:
std::vector<UserData> getUserInformation();
private:
struct InternalData;
InternalData* m_internal_data;
};
然后,在您的
.cpp
文件中:struct CODBCHelper::InternalData
{
SQLHENV m_henv;
SQLHDBC m_hdbc;
SQLHSTMT m_hstmt;
};
现在,您将实现更改为使用
m_internal_data
而不是分别使用每个组件。如果要更新您的软件,这特别有利可图-它禁止客户端创建代码,这取决于您类型的实现细节。您可能还想阅读this answer的第2点和/或4.点。
关于c++ - 我们可以在头文件中隐藏不重要的声明吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30244594/