我来自 C# 背景,最近开始学习 C++。我遇到的一件事是 pimpl 成语。我为一些大公司做过 C# 开发,但从未遇到过。
也许这是错误的,但我的理解是在 C++ 中这是必要的,因为使用了头文件并且没有部分类选项。
但是在 C# 中,我们总是会使用类库来构建应用程序。如果库代码发生变化,我们会将其重新编译为 dll 并在应用程序项目中引用新的 dll。
我真的不明白为什么不能用 C++ 做同样的事情。Pimpl 对我来说只是一个丑陋的黑客。
我来自 C# 背景,最近开始学习 C++。我遇到的一件事是 pimpl 成语。我为一些大公司做过 C# 开发,但从未遇到过。
也许这是错误的,但我的理解是在 C++ 中这是必要的,因为使用了头文件并且没有部分类选项。
但是在 C# 中,我们总是会使用类库来构建应用程序。如果库代码发生变化,我们会将其重新编译为 dll 并在应用程序项目中引用新的 dll。
我真的不明白为什么不能用 C++ 做同样的事情。Pimpl 对我来说只是一个丑陋的黑客。
c#中使用了pimpl成语吗?
这取决于你所说的这个成语是什么意思。
所讨论的习惯用法本质上是将类型的实现细节分成一个类,并将公共表面区域分成一个包装类,该类简单地保存一个指向实现类的指针。
这有两个好处。
首先,在 C++ 中,它可以导致编译时间的改进,因为公共表面区域的消费者只需要解析包含公共表面区域的头文件;他们不需要解析包含实现细节的头文件。
其次,它导致接口与实现非常清晰的分离;实现可以完全改变而不会对消费者产生任何影响,因为消费者永远不会看到实现细节。
第一个好处是在 C# 中无关紧要。C# 编译器很快。(在很大程度上当然是因为该语言被设计为可以快速编译。)
第二个好处是在 C# 中非常有用。在 C# 中,实现此模式的惯用方式是创建一个执行“真正”工作的私有嵌套类和一个只是具有公共表面区域的外观的公共类。
我在 C# 中特别喜欢的一种技术是使公共类成为私有嵌套类的基类,为基类提供私有构造函数以防止第三方扩展,并使用工厂模式分发私有嵌套类的实例。
我真的不明白为什么不能用 C++ 做同样的事情。
然后我鼓励你尝试编写一个 C++ 编译器来做这件事。你要么成功地创建了一个更快的 C++ 编译器,要么你会发现为什么同样的事情不能在 C++ 中完成。无论哪种方式,您都会受益!
是的,它是(“黑客”)。它是由 ANSI C++ 的基于文本的编译模型引起的:编译器需要查看代码的文本表示,以便生成有用的东西。不是必须这样,但今天就是这样。
正如 Eric 所指出的,pimpl 成语有两个目的。我只想补充一点,第二个目的(分离接口和实现)是众所周知的软件设计模式之一:桥接(我认为也称为句柄/主体)。你可以在这里阅读更多关于它的信息