gpt4 book ai didi

c++ - 避免在头文件中包含私有(private)方法所需的内容

转载 作者:搜寻专家 更新时间:2023-10-31 00:12:02 24 4
gpt4 key购买 nike

与特定任务相关的类依赖于特定的第 3 方库来执行此任务(比方说 JSON 序列化)。库的使用对客户端应该是透明的,并且类的公共(public)接口(interface)中没有引用任何第 3 方代码类或数据类型。

在引入私有(private)方法之前,我可以将所需的 #include 添加到 .cpp 文件中。但是,现在我根据第 3 方代码声明了一个私有(private)方法,我必须将一些#includes 提取到头文件中,这反过来导致将相应的头文件包含在所有其他文件中,包括我的类的头文件。

我正在考虑使用函数而不是私有(private)方法,这样我就不必在 header 中声明函数。当然,我必须将对我正在使用的字段的引用传递给这些函数。这是解决此问题的合理方法,还是在使用私有(private)方法时有实现这种封装的最佳实践?

最佳答案

假设你必须添加那些私有(private)方法

  • 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,在header中你只需要前向声明

namespace Json
{
class Node;
}

代替

#include <3rdLibrary/Json.hpp>

如果 Json 是一个类并且 Json::Node 是一个内部类,则不能使用前向声明

免费功能如果该函数不需要私有(private)访问(以及其他一些不需要虚拟的东西),您可以创建自由函数(在未命名的命名空间或 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));
/**/
}

PIMPL 成语Pimpl 习语是另一种选择

// 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;
};

源码

// 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.

注意:使用 pimpl idiom 可能只隐藏部分实现

界面

最后,类似于 pimpl 习语,你可以使用接口(interface)

// 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);

并正常实现MyClass(使用override)(它的头文件只被它的cpp文件使用)

并实现

std::unique_ptr<IMyClass> makeMyClass(Args args) { return std::make_unique<MyClass>(args); }

注意:可以通过接口(interface)只暴露一部分(只隐藏一部分代码)。

关于c++ - 避免在头文件中包含私有(private)方法所需的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31723990/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com