在这种情况下,我应该使用嵌套类吗?

58

我正在开发一组用于视频播放和录制的类集合。我有一个主类,它充当公共接口,具有像play()stop()pause()record()等方法。然后我有工作类来进行视频解码和视频编码。

我刚刚了解到C++中嵌套类的存在,并且很想知道程序员对使用它们的看法。我有点谨慎,不太确定利弊是什么,但它们似乎(根据我正在阅读的书)在像我这样的情况下使用。

这本书建议,在像我这样的场景中,一个好的解决方案是将工作类嵌套在接口类中,这样就没有为客户端不应使用的类单独的文件,并避免任何可能的命名冲突。我不知道这些理由是否正确。嵌套类是一个新的概念对我来说。只是想看看程序员对这个问题的看法。

10个回答

30
我有点不太愿意在这里使用嵌套类。如果您为“多媒体驱动程序”创建一个抽象基类来处理后端工作(工作核心),并为前端工作创建一个单独的类呢?前端类可以获取指向已实现的驱动程序类(适用于相应的媒体类型和情况)的指针/引用,并对工作核心结构执行抽象操作。
我的哲学是去提供两个结构的精美访问方式,假设它们将一起使用。
我会参考Qt中的QTextDocument。您可以直接访问裸金属数据处理的接口,但将授权委托给像QTextEdit这样的对象进行操作。

9
您可以使用嵌套类来创建一个(小型)帮助程序类,该类是实现主类所必需的。或者例如,定义一个接口(具有抽象方法的类)。
在这种情况下,嵌套类的主要缺点是这使得它们更难被重复使用。也许您想在另一个项目中使用VideoDecoder类。如果将其作为VideoPlayer的嵌套类,则无法以优雅的方式执行此操作。
相反,将其他类放在单独的.h/.cpp文件中,然后可以在VideoPlayer类中使用它们。 VideoPlayer的客户端现在只需要包含声明VideoPlayer的文件,仍然不需要知道您如何实现它。

5

决定是否使用嵌套类的一种方法是考虑这个类是起到支持作用还是独立存在。

如果它仅仅是为了帮助另一个类而存在,那么我通常会将其设为嵌套类。当然,这其中还有许多注意事项,其中一些似乎是相互矛盾的,但最终还是要靠经验和直觉。


4

我们遇到了一个问题,涉及到半老化的Sun C++编译器和嵌套类的可见性,这种行为在标准中发生了变化。当然,这并不是不使用嵌套类的理由,只是需要注意如果您计划在包括旧编译器在内的许多平台上编译软件时,请注意此问题。


4
如果您在接口类中使用指向工作类的指针,并且不将它们公开为接口方法的参数或返回类型,那么您就不需要在接口头文件中包含这些工作类的定义(只需前向声明即可)。这样,接口使用者就不需要了解后台的类。
您绝对不需要为此嵌套类。实际上,单独的类文件会使您的代码更加易读和易于管理,随着项目的发展,这也会帮助您。如果您需要进行子类化(例如针对不同的内容/编解码器类型),这也会对您有所帮助。
这里有关于PIMPL模式的更多信息(3.1.1节)。

4

4
有时候,将实现类隐藏在用户视野之外是比较合适的。这种情况下,最好将它们放在 foo_internal.h 中而不是公共类定义中。这样,在阅读 foo.h 的时候,用户就不会看到你不想让他们看到的内容,但你仍然可以针对接口的每个具体实现编写测试。

2
你应该仅在无法使用外部类的公共接口将其实现为单独的类时,才应该使用内部类。内部类会增加类的大小、复杂度和责任,因此应该谨慎使用。
你的编码器/解码器类听起来更适合使用策略模式

1
避免使用嵌套类的一个原因是,如果您打算使用swig(http://www.swig.org)将代码包装以便与其他语言一起使用,那么就需要避免使用嵌套类。Swig目前存在嵌套类的问题,因此与公开任何嵌套类的库进行接口交互会变得非常麻烦。

1

还要记住的一件事是,您是否曾经设想过不同实现的工作函数(例如解码和编码)。在这种情况下,您肯定需要一个抽象基类和实现这些函数的不同具体类。为每种类型的实现嵌套一个单独的子类并不真正合适。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接