我正在研究用于视频播放和录制的类集合。我有一个主要类,它的作用类似于公共接口,使用play()
,stop()
,pause()
,record()
等方法...然后我有一些主要的类来执行视频解码和视频编码。
我刚刚了解了C ++中嵌套类的存在,我很想知道程序员对使用它们的想法。我有点小心谨慎,并不确定它的好处/缺点是什么,但它们似乎(根据我正在阅读的书)在我的案例中使用。
本书建议在像我这样的场景中,一个很好的解决方案是将主要类嵌套在接口类中,因此客户端不打算使用的类没有单独的文件,并且避免任何可能的命名冲突?我不知道这些理由。嵌套类对我来说是一个新概念。只是想看看程序员对这个问题的看法。
答案 0 :(得分:25)
我有点不愿意在这里使用嵌套类。如果您为“多媒体驱动程序”创建了一个抽象基类来处理后端内容(主力),以及为前端工作创建一个单独的类,该怎么办?前端类可以获取指向实现的驱动程序类的指针/引用(针对适当的媒体类型和情况),并对主力结构执行抽象操作。
我的理念是继续以优雅的方式让客户接触到这两种结构,只是假设它们会串联使用。
我会在Qt中引用类似QTextDocument的内容。您提供了裸机数据处理的直接接口,但将权限传递给像QTextEdit这样的对象来进行操作。
答案 1 :(得分:9)
您将使用嵌套类来创建实现主类所需的(小)辅助类。或者,例如,定义一个接口(一个带抽象方法的类)。
在这种情况下,嵌套类的主要缺点是这使得重用它们变得更加困难。也许你想在另一个项目中使用你的VideoDecoder类。如果你把它作为一个嵌套的VideoPlayer类,你就不能以优雅的方式做到这一点。
相反,将其他类放在单独的.h / .cpp文件中,然后可以在VideoPlayer类中使用这些文件。 VideoPlayer的客户端现在只需要包含声明VideoPlayer的文件,但仍然不需要知道如何实现它。
答案 2 :(得分:5)
决定是否使用嵌套类的一种方法是考虑这个类是否起支持作用或者它自己的作用。
如果它仅仅是为了帮助另一个类而存在,那么我通常会将它作为一个嵌套类。对此有一大堆警告,其中一些似乎是矛盾的,但这一切都归结为经验和直觉。
答案 3 :(得分:4)
听起来像是可以使用strategy pattern
的情况答案 4 :(得分:4)
有时隐藏用户的实现类是适当的 - 在这些情况下,最好将它们放在foo_internal.h中而不是公共类定义中。这样,你的foo.h的读者就不会看到你不喜欢的东西,但你仍然可以针对你的界面的每个具体实现编写测试。
答案 5 :(得分:4)
我们遇到了一个半旧的Sun C ++编译器的问题,以及标准中行为发生变化的嵌套类的可见性。当然,如果您打算在包括旧编译器在内的许多平台上编译软件,这不是不进行嵌套类的理由。
答案 6 :(得分:4)
好吧,如果您在Interface类中使用指向您的主力类的指针,并且不将它们作为参数公开或在接口方法中返回类型,则不需要在接口头文件中包含这些工作马的定义(你只需转发声明它们)。这样,您的界面的用户将不需要知道后台的类。
你绝对不需要为此嵌套类。实际上,单独的类文件实际上会使您的代码在项目增长时更易读,更易于管理。如果你需要子类(比如针对不同的内容/编解码器类型),它也会在以后帮助你。
以下是有关PIMPL pattern的更多信息(第3.1.1节)。
答案 7 :(得分:2)
只有当你不能使用可能的外部类'公共接口将它作为一个单独的类实现时,才应该使用内部类。内部类增加了类的大小,复杂性和责任,因此应该谨慎使用它们。
您的编码器/解码器类听起来更适合Strategy Pattern
答案 8 :(得分:1)
避免嵌套类的一个原因是,如果您打算使用swig(http://www.swig.org)包装代码以与其他语言一起使用。 Swig目前在嵌套类方面存在问题,因此与暴露任何嵌套类的库进行交互变得非常痛苦。
答案 9 :(得分:1)
要记住的另一件事是你是否想过你的工作函数的不同实现(例如解码和编码)。在这种情况下,您肯定需要一个具有不同具体类的抽象基类来实现这些功能。为每种类型的实现嵌套一个单独的子类是不合适的。