在c++中屏蔽尽可能多的类实现

Masking as much as possible of class implementation in C++

本文关键字:实现 尽可能 c++ 屏蔽      更新时间:2023-10-16

我有两个类AB,其中B使用A类的对象,如下所示

class A {
    private:
        int foo_;
    A(const int &foo): foo_(foo) {}
}
class B {
    // STUFF
    inline C operator()(A a)
}

目前,我已经将两者的定义放在.h文件中,代码编译并正确执行。

我的问题是:我可以屏蔽多少类A的实现,例如通过将代码行移动到.cpp文件进行单独编译和链接?我可以屏蔽private成员和方法的实现(外部用户不能直接访问的所有内容)吗?如何?我应该使用哪些c++关键字?

非常感谢。

屏蔽实现可以通过PIMPL习惯用法或使用简单的多态性来完成,这是一种工厂方法模式。基本上,您创建了一个接口类,如IA:

/* File: A.h */
#include <memory> /* For std::shared_ptr */
class IA;
/* Change the line below to boost::shared_ptr<> or
 * another implementation of a shared-pointer.
 * Read more:
 * http://en.wikipedia.org/wiki/Smart_pointer#shared_ptr_and_weak_ptr
 */
typedef std::shared_ptr<IA> APtr;
class IA {
public:
    static APtr Create(const int foo);
    IA(){}
    virtual ~IA(){}
    virtual void somePublicMethod() = 0;
};

在你的a.p中,你会有它的实现:

/* File: A.cpp */
#include "A.h"
class A : public IA
{
public:
    A(const int foo):foo_(foo){}
    void somePublicMethod(){/* Your awesome implementation goes here */}
};
APtr IA::Create(const int foo)
{
    return APtr(new A(foo));
}

通过这种方式,您只传递接口并只向外部公开公共方法,其内部结构在您的CPP文件中。

优势:

  • 对用户完全隐藏实现

缺点:

  • 你需要为每个你想隐藏的类创建一个接口
  • 用户必须调用工厂方法来创建实例。例如上面示例中的Create()
  • 你将总是让你的类实例在堆内存中而不是在堆栈中,也就是说,你的实现实例将总是必须是一个指针。(阅读更多:堆与堆栈内存)

如果您不需要C operator()(A a)inline,您可以转发声明参数A,如下所示

class A;

然后你可以将它的定义移动到另一个头文件中,并将它包含在使用它的地方。

关于pImpl习语可以隐藏的内容:

  • 可以将所有函数定义(包括构造函数和它们的初始化列表)移动到Impl
  • 允许您将私有类型、数据成员函数放入Impl类中,除非它们影响类的行为(例如私有构造函数、析构函数和操作符对类的用户有影响)
  • 可以将类静态数据成员的定义和初始化移动到实现文件
  • 根据Arne的评论,私有基类通常可以移动到实现中(除非你在公共或受保护的数据成员中使用typedef等,根据他的评论,这是丑陋的!)