【问题标题】:class library and pimpl - splitting class accessibility类库和 pimpl - 拆分类可访问性
【发布时间】:2013-08-18 07:12:26
【问题描述】:

我想使用 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();
    }
}

有更好的方法吗?

【问题讨论】:

  • 你为什么需要它?最简单的方法是只将公共方法放在用户类中,并将所有血淋淋的细节留给实现。
  • 不是重复的:这个问题更具体。除非考虑到每个关于 pimpl 的问题都是重复的......
  • 我认为这里的所有内容都包含在该帖子中。 :) 这些话题一次又一次地被过度讨论。除了一般原则之外,我在这里没有看到任何具体内容。

标签: c++ pimpl-idiom


【解决方案1】:

各有利弊。

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

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

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

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

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

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

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

【讨论】:

  • 其实pimpl现在还是很常见的,所以“越来越没吸引力”可能会被别人理解。它仍然很有吸引力。事实上,尽管有这篇文章,我个人还是建议使用 pimpl idiom。可能更糟糕的是这 1-2 种方式的朋友。
  • @LaszloPapp:那么标准库是最糟糕的,至少对你来说。不过别担心,这是一场老生常谈:见stackoverflow.com/questions/1093618/…
  • 不,我没有说它最终是坏的。我说对于这种情况,这不是正确的选择,IMO。 :-)
猜你喜欢
  • 1970-01-01
  • 2013-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-02
  • 2011-08-27
  • 1970-01-01
相关资源
最近更新 更多