问题标签 [pimpl-idiom]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
337 浏览

c++ - 你如何与 Pimpl 交换私人数据而不暴露你的内部信息?

如果您有一个对象 B 需要对象 A 的私有成员的副本,并且私有成员被 Pimpl 隐藏,您如何在不暴露您的内部结构的情况下实现它?// Foo.h

0 投票
2 回答
512 浏览

c++ - 使用 pimpl-idiom 创建库

我正在尝试为将使用 pimpl-idiom 的库定义接口。以下是我定义的典型接口类。

函数 func1()、func2() 是接口函数。而notif1()、notif2()是应用程序必须实现的通知函数(在A的子类中)。

这是为库定义接口的正确方法吗?这种方法有什么缺点还是有更好的解决方案?


感谢所有的答案。因此,从所有答案中,我收集到以下是表示库接口的好方法。

接口库将实现接口函数,应用程序将在派生类中实现通知函数。有没有遵循这种模式的图书馆的好例子?

0 投票
2 回答
1261 浏览

c++ - pimpl 中的方法是内联的吗?

考虑下一个简单的例子:

标题:

实施:

主要的 :

问题是:
该方法A::Imp::foo会被内联到A::foo吗?
它是否取决于该方法中的实现?

PS我正在使用gcc(如果重要的话是4.3.0)。

编辑

我想我解释得不是很好。我的真正意思是这个。如果我使用最大优化级别,是// do something and return the result要放在A::foo()or中A::Imp::foo()吗?
没有优化,我看到这还没有完成(the pimpl->foo()仍然被调用)。

我知道 A::foo() 永远不会在 main() 中内联,但这不是我要问的。

0 投票
5 回答
955 浏览

c++ - 来自 Code Complete 关于封装的 C++ 建议?

在 Code Complete 的“良好封装”部分,建议隐藏私有实现细节。C++ 中给出了一个示例。这个想法基本上是将接口与实现完全分离,即使在类级别也是如此。

这真的是一种很好的时间利用方式吗?这不仅看起来效率低下(这会带来什么样的性能损失?),而且代码完整(“管理复杂性”)的整个座右铭似乎已经被颠倒了——这不会增加复杂性吗?

0 投票
4 回答
3247 浏览

c++ - Pimpl 成语和内部对象协作没有朋友声明

我正在使用 pimpl 习惯用法实现几个类,并且遇到了一些设计问题。

首先,我总是看到 pimpl 这样做

我有几个使用这种方法的类,我的问题是其中几个类需要访问彼此的实现细节,但是 _pimpl 指针是私有的。

任何人都可以看到将 _pimpl 公开的不利之处。显然,如果它是公开的,那么有人可能会意外(或故意)重新分配它。(我忽略了“私人”可以被#定义为“公共”并授予访问权限这一事实。如果你这样做,那么你应该得到你所得到的)。

我很欣赏我的设计可能存在缺陷,并且也欢迎任何关于这些方面的评论。

我真的很讨厌使用朋友,并且不确定他们是否会提供帮助,因为您无法在没有完全定义 Object 的情况下转发声明 Object::ObjectImpl。

IE

谢谢马克。

* 更新 - 更多细节 **

我有两个类,一个叫做命令,另一个叫做结果。我在 Command 上有返回结果向量的方法。

命令和结果都使用 pimpl 习惯用法。我希望结果的接口尽可能小。

现在在 Command::getResults() 中。我将 ResultsImpl 注入到结果中。在 Command::prepareResults() 中,我需要访问 ResultsImpl。

M。

0 投票
2 回答
300 浏览

c - 类型转换结构以隐藏实现与 pimpl-idiom

我知道在 C 中看起来像这样的 pimpl-idiom:

但是,通过类型转换,我可以摆脱不透明的指针并减少有人弄乱实现的可能性:

在后一种情况下,任何对 FooBar 进行操作的函数都将简单地类型转换为 FooBarImpl 以访问“私有”成员。

例如,如果有人向 FooBar 添加一些成员但对 FooBarImpl 不这样做,我可以看到这将如何成为一个问题。但是在我的情况下 FooBar 将只包含一个成员并且不太可能改变。

当我希望隐藏实现细节时,这会被认为是一种好的做法,还是应该坚持使用 pimpl-idiom?

谢谢你。

0 投票
2 回答
335 浏览

c++ - PIMPL,POD,实现类的可见性,它的析构函数会被调用吗?

维基百科在关于不透明指针的文章中声称,

d 指针是类的唯一私有数据成员,并指向结构的实例(必须是 POD,因为它的析构函数不可见)

这在 PIMPL 中不是必需的,只是维基百科通常是特殊的,不是吗?

我将缺少 d-pointer 标签作为我的问题的答案,但希望有人可以为维基百科做出贡献和/或澄清事情。或者只是说维基百科很糟糕,最后的手段等等:)

我的问题的重点是,当在 cpp 实现文件中完全声明和定义嵌套类的方法时,它的可见性如何?它的析构函数会按预期调用吗(包含类将在其析构函数中对其调用 delete)?

_编辑_ 固定版本,http ://en.wikipedia.org/wiki/Opaque_pointer

0 投票
5 回答
1166 浏览

c++ - 带有模板类的 pimpl 习语有什么优势吗?

据我了解,pimpl 习惯用法的主要好处是将数据成员隐藏在实现文件中而不是标题中。但是,模板需要在头文件中完全定义,以便编译器按需实例化它们。在这种情况下,将 pimpl 习惯用法用于模板类有什么好处?

0 投票
2 回答
805 浏览

c++ - 实现 pimpl idiom 时出现链接器错误

对提供者进行了更清晰的编辑。很抱歉让大家感到困惑。

这是在 Windows 下。

我有一个使用 pimpl 习惯用法实现类的静态库。pimpl 标头不仅由消费代码使用,而且还链接到静态库。然而,当我编译消费代码 (.exe) 时,链接器会抱怨pimpl 标头应该隐藏的实现类上未解析的外部。

这怎么可能?

当我编译/链接 Bar.exe 时,链接器抱怨它无法解析 FooImpl。我忘记了它到底说了什么,因为我现在无法访问我的工作电脑,但这就是它的要点。这个错误对我来说没有意义,因为走 pimpl 路线的目的是让 Bar.exe 不必担心 FooImpl。

确切的错误是这样的:

1>Foo.lib(Foo.obj) : error LNK2019: unresolved external symbol "public: __thiscall FooImpl::FooImpl(void)" (??0FooImpl@@QAE@XZ) 在函数 "public: __thiscall Foo::Foo (void)" (??0Foo@@QAE@XZ)

0 投票
3 回答
429 浏览

c++ - 避免在 C++ 类中泄漏外部类型

我在这样的标题中定义了一个类(缩写):

cairo_t 和 cairo_surface_t 是由Cairo图形库定义的类型。

我遇到的问题是,如果我想使用这个类或其来自另一个库或应用程序的派生类,我还需要包含 cairo 标头,因为我通过 CairoRenderer 标头“泄漏”了 cairo 类型。我希望同一个库中的此类(或其任何子类)可以在外部使用,而无需包含 cairo 标头或链接到 cairo 库。

所以接下来我尝试的是按照Wikipedia示例使用 pimpl 技术,因为它看起来可以完成我想要实现的目标:

CairoRenderer.h(缩写)

CairoRenderer.cpp(缩写)

我遇到的问题是,当我尝试从派生类访问 m_pimpl 成员时,出现编译器错误:

我做错了吗?还是我想做的甚至可能?