类库和pimpl - 拆分类可访问性

时间:2013-08-18 07:12:26

标签: c++ pimpl-idiom

我想使用pimpl习惯用法创建一个类库,这样我就可以为库的用户隐藏我的实现细节。

是否可以创建一个类,其中某些方法是公共的,并且可以从用户的角度调用,同时具有只能从内部调用的方法。

现在我只看到一个带有friend关键字的解决方案,并声明内部方法是私有的。

例如: MyPartiallyVisibleClass:包含用户可访问的方法混合的类,以及只能由库的内部访问的方法。 InternalClass:库内部的类。用户永远不会知道这个问题。

// MyPartiallyVisibleClass.h: Will be included by the user.
class MyPartiallyVisibleClass
{
private:
    class Impl;          // Forward declare the implementation
    Impl* pimpl;

    InternalMethod();    // Can only be called from within the library-internals.

public:
    UserMethod();       // Will be visible and callable from users perspective.
}

// MyPartiallyVisibleClass.cpp
class MyPartiallyVisibleClass::Impl
{
private:
    InternalMethod();

public:
    UserMethod();

    friend class InternalClass;
}

// Internal class that will not be included into users application.
class InternalClass
{
public:
    InternalMethod()
    {
        MyPartiallyVisibleClass pvc;
        pvc.InternalMethod();
    }
}

有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

有利有弊。

从源角度来看,如果只分发标题和二进制文件,源用户将看不到cpp文件中的所有内容。

所以,MyPartiallyVisibleClass::Impl::Usermethod也是不可见的,但是在声明的cpp文件中无处可见,可以调用。

如果您不想在内部重复外部方法,则可能需要外部和内部类之间的单向或双向友谊。它似乎是一个封装中断,但它不是,因为这里的“胶囊”是外部类。如果一切都在你的同一责任之下,那么创建复杂的内部隐私层级(公共外部,私人外部,公共内部私人内部公众甚至更内部......等)可能变得毫无头绪。除非内部部分如此之大以致分配给不同的开发人员,否则另一级别的界面和需要实施。

然而,从二进制用户角度来看,每个没有内联的函数都存在,并且 - 具有外部链接 - 它的名称可以在库中使用,因此它可以通过编写另一个标题来“调用”,使其可以公开使用其他来源。我将只是一个没有文档的功能。

公共/私人等的概念是为了代码安全(避免使用您不希望保持的功能,始终保持相同的“合同”可用,从而使外部代码更加稳定,消除不必要的依赖)对于“安全”(避免谁想打电话找到一种方式来打电话)。

还有另一个缺点:模板无法隐藏到源中,因为它们必须扩展到用户的源代码空间(而不是开发人员二进制空间)。通用编程,功能静态多向性等的发展使得pimpl成语越来越没有吸引力。

现在有许多程序由单个cpp文件生成,它实例化一个“管理器对象”,其整个功能由仅包含标头的库组成。既然相信与否,这种编程方式使代码在编译器之间更加可移植,因为对于每个可能的客户端编译器,它不必以不同的二进制形式存在。并不一定会使构建时间更长:对于不经常更改的代码,可以生成一次预编译头。谁在乎用户是否可以看到代码?如果他想使用它而得到支持则不适合改变它。如果他想破解或偷走,他会发现另一种方法。

相关问题