与特定任务相关的类依赖于某个第三方库来执行此任务(比如 JSON 序列化)。该库的使用对于客户端应该是透明的,并且该类的公共接口中不会引用任何第三方代码类或数据类型。
在引入私有方法之前,我只需将所需的#includes 添加到 .cpp 文件即可。但是,现在我根据第 3 方代码声明了一个私有方法,我必须将一些 #include 拉到头文件中,这反过来又导致在所有其他文件(包括我的类的头文件)中包含相应的头。
我正在考虑使用函数而不是私有方法,这样我就不必在标头中声明函数。当然,我必须将对我正在使用的字段的引用传递给这些函数。这是解决此问题的合理方法吗?或者是否有在使用私有方法时实现这种封装的最佳实践?
假设您必须添加那些私有方法
Json::Node AsJson() const;std::string Serialize(const Json::Node& root) const;Json::Node Unserialize(const std::string& document) const;void InitFrom(const Json::Node&);前向声明
假设Json是一个namespace,在标头中你只需要前向声明
namespace Json
{
class Node;
}
Run Code Online (Sandbox Code Playgroud)
代替
#include <3rdLibrary/Json.hpp>
Run Code Online (Sandbox Code Playgroud)
如果Json是一个类并且是Json::Node一个内部类,则不能使用前向声明
自由函数
如果函数不需要私有访问(以及其他一些不需要虚拟的东西),您可以创建自由函数(在未命名的命名空间或static)
所以 header 和 cpp 中没有任何内容:
#include <3rdLibrary/JsonCpp.hpp>
namespace {
Json::Node AsJson(const MyClass& myclass) {/**/}
std::string Serialize(const MyClass& myclass, const Json::Node& root) {/**/}
Json::Node Unserialize(const MyClass& myclass, const std::string& document) {/**/}
void InitFrom(MyClass& myclass, const Json::Node&){/**/}
}
MyClass::foo()
{
Serialize(*this, AsJson(*this));
/**/
}
Run Code Online (Sandbox Code Playgroud)
PIMPL IDIOM Pimpl idiom 是另一种选择
// header.hpp
class MyClass
{
public:
~MyClass();
MyClass(const MyClass&); // = delete ?
MyClass& operator =(const MyClass&); // = delete ?
MyClass(MyClass&&); // = delete ?
MyClass& operator =(MyClass&&); // = delete ?
// previous public methods.
private:
struct Pimpl;
std::unique_ptr<Pimpl> pimpl;
};
Run Code Online (Sandbox Code Playgroud)
并在源中
// MyClass.cpp
struct Pimpl
{
// What you should have done in MyClass
};
MyClass::~MyClass() = default; // which destroys Pimpl and should know Pimpl definition
// that's why it is not in header
ReturnType MyClass::publicMethod(Args args) {return pimpl->publicMethod(args);} // Same for all public methods.
Run Code Online (Sandbox Code Playgroud)
注意:可能可以使用 pimpl idiom 仅隐藏部分实现
界面
最后,与 pimpl 惯用语类似,您可以使用接口
// IMyClass.hpp
class IMyClass
{
public:
virtual ~IMyClass() = default;
IMyClass(const IMyClass&); // = delete ?
IMyClass& operator =(const IMyClass&); // = delete ?
IMyClass(IMyClass&&); // = delete ?
IMyClass& operator =(IMyClass&&); // = delete ?
// previous public methods but virtual.
};
std::unique_ptr<IMyClass> makeMyClass(Args);
Run Code Online (Sandbox Code Playgroud)
并正常实现MyClass(使用override)(其标头仅由其 cpp 文件使用)
并还实施
std::unique_ptr<IMyClass> makeMyClass(Args args) { return std::make_unique<MyClass>(args); }
Run Code Online (Sandbox Code Playgroud)
注意:可能可以通过接口仅公开某些部分(仅隐藏代码的某些部分)。
| 归档时间: |
|
| 查看次数: |
1131 次 |
| 最近记录: |