尽可能多地屏蔽C ++中的类实现

时间:2013-06-11 08:00:10

标签: c++ class

我有两个类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 ++关键字?

非常感谢你。

3 个答案:

答案 0 :(得分:4)

掩码实现可以通过PIMPL idiom或使用简单的多态(Factory method pattern来完成。基本上,你创建一个接口类,比如说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.cpp中,您将拥有它的实现:

/* 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()
  • 您的类实例总是在堆内存中而不是在堆栈中,即您的实现实例始终必须是指针。 (阅读更多:Heap vs. Stack Memory

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

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

class A;

然后,您可以将其定义移动到另一个标题,并将其包含在它使用的位置。

以下是有关forward declaration的详细信息。