0

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

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

现在我只看到一个带有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();
    }
}

有没有更好的方法来做到这一点?

4

1 回答 1

0

有优点也有缺点。

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

所以,也不MyPartiallyVisibleClass::Impl::Usermethod是可见的,而是公开的,在它被声明的 cpp 文件中的任何地方都可以调用。

如果您不想在内部重复外部方法,则可能需要外部和内部类之间的零方式、一种方式或两种方式的友谊。这似乎是一个封装中断,但事实并非如此,因为这里的“胶囊”是外部类。如果所有事情都由您承担相同的责任,那么创建内部隐私的复杂层次结构(公共外部,私人外部,公共内部私人内部公共甚至内部......等)可能会变得毫无头绪。除非内部部分太大而无法分配给不同的开发人员,否则需要另一个级别的接口和实现。

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

公共/私有等的概念是为了代码安全(避免你不想承诺维护的功能始终可用相同的“合同”,从而使外部代码更稳定,消除不必要的依赖)而不是为了“安全"(避免想打电话的人想办法打电话)。

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

今天有许多由单个 cpp 文件创建的程序,它们实例化单个“管理器对象”,其整个功能都由仅标头库组成。信不信由你,这种编程方式使代码在编译器之间更加可移植,因为对于每个可能的客户端编译器,它不必以不同的二进制形式存在。并且不一定会使构建时间更长:对于不经常更改的代码,可以生成一次预编译头文件。谁在乎用户可以看到代码?如果他想使用它并得到支持,那么不当更改它不是他的利益。如果他想破解或偷窃,他无论如何都会找到另一种方法来做到这一点。

于 2013-08-18T07:41:56.000 回答