我们可以在头文件中隐藏不重要的声明吗?
Can we hide unimportant declarations in Header files?
我最近决定将我的一些函数导出到一个静态库(.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头文件:
// 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习惯用法:
//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
而不是单独的每个组件。如果你的软件要更新,这是特别有利可图的——它禁止客户端创建代码,这取决于你的类型的实现细节。
您可能还需要读取点2。和/或
可以公开接口,而不是类+工厂类。这样你的用户就看不到你实际类的构造,一切都很好。
例如,你的用户得到这个:
class ICODBCHelper
{
public:
virtual ~ICODBCHelper();
public:
virtual std::vector<UserData> getUserInformation();
};
class MyFactory
{
public:
ICODBHelper *CreateCODBHelper();
}
,你实现这个:
class CODBCHelper : public ICODBHelper
{
public:
CODBCHelper();
virtual ~CODBCHelper();
public:
std::vector<UserData> getUserInformation();
private:
SQLHENV m_henv;
SQLHDBC m_hdbc;
SQLHSTMT m_hstmt;
};
创建一个具有纯虚方法的public抽象类,不包含数据。然后创建一个工厂/访问器来实例化/访问库代码中的实际对象,该对象实际上是抽象类的派生/具体类。
- 函数调用中参数的顺序重要吗
- 为什么我的程序在读取/写入文件时会删除最重要的数字?
- 运行时与编译时多态性:更好的可读性与编译时错误检查,更重要的是
- 对于为什么放置在标题文件中很重要的原因感到困惑
- 将所有位低于最重要的设置位零的最有效方法是什么?
- 空格很重要的另一种情况(也许?
- 正整数 uniq 的组合(顺序不重要)
- P2P最重要的基础知识
- 哪些是安卓系统中不可用的最重要的POSIX功能
- boost::function 和 std::tr1::function 之间是否有重要的区别需要了解
- 如何在C++中获取字符中最不重要的部分
- 基类初始化器和成员变量初始化器的顺序重要吗
- 在IDE中运行程序和通过.exe运行程序之间有重要的区别吗?
- Direct3D COM接口发布的顺序重要吗?
- 提升启用/disable_if功能对的顺序重要吗?
- 不是最重要的const.但这是什么
- c++: obj文件链接的顺序重要吗?
- 位操作 - 如何在C++中获取字符中最不重要的 3 位
- 我们可以在头文件中隐藏不重要的声明吗?
- 基数排序,最重要的先排序或者最不重要的先排序,这样更快