58

我正在研究一组用于视频播放和录制的类。我有一个主类,它的作用类似于公共接口,具有类似、、、等的方法......play()然后我有主力类,它们执行视频解码和视频编码。stop()pause()record()

我刚刚了解了 C++ 中嵌套类的存在,我很想知道程序员对使用它们的看法。我有点警惕,不确定有什么好处/缺点,但它们似乎(根据我正在阅读的书)可用于我的情况。

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

4

10 回答 10

30

我有点不愿意在这里使用嵌套类。如果您为“多媒体驱动程序”创建一个抽象基类来处理后端工作(主力),并为前端工作创建一个单独的类怎么办?前端类可以获取已实现驱动程序类的指针/引用(针对适当的媒体类型和情况),并对主力结构执行抽象操作。

我的理念是继续前进,让客户以一种优雅的方式访问这两种结构,只是假设它们会被串联使用。

我会在 Qt 中引用类似QTextDocument的东西。您为裸机数据处理提供直接接口,但将权限传递给 QTextEdit 之类的对象以进行操作。

于 2008-08-02T03:00:24.613 回答
9

您将使用嵌套类来创建实现主类所需的(小)辅助类。或者例如,定义一个接口(一个具有抽象方法的类)。

在这种情况下,嵌套类的主要缺点是这使得重用它们变得更加困难。也许您想在另一个项目中使用您的 VideoDecoder 类。如果将其设为 VideoPlayer 的嵌套类,则无法以优雅的方式执行此操作。

相反,将其他类放在单独的 .h/.cpp 文件中,然后您可以在 VideoPlayer 类中使用这些文件。VideoPlayer的客户端现在只需要包含声明VideoPlayer的文件,仍然不需要知道你是如何实现它的。

于 2008-09-17T11:50:28.090 回答
5

决定是否使用嵌套类的一种方法是考虑这个类是起辅助作用还是它自己的一部分。

如果它只是为了帮助另一个类而存在,那么我通常将其设为嵌套类。对此有很多警告,其中一些似乎是矛盾的,但这一切都归结为经验和直觉。

于 2008-08-05T08:29:13.527 回答
4

听起来像是您可以使用策略模式的情况

于 2008-08-05T08:37:19.097 回答
4

有时对用户隐藏实现类是合适的——在这些情况下,最好将它们放在 foo_internal.h 中而不是放在公共类定义中。这样,您的 foo.h 的读者将不会看到您希望他们不为之烦恼的内容,但您仍然可以针对您的接口的每个具体实现编写测试。

于 2008-09-16T09:31:01.600 回答
4

我们遇到了一个半旧的 Sun C++ 编译器和嵌套类的可见性问题,这些问题在标准中发生了变化。当然,这不是不做嵌套类的理由,如果您计划在包括旧编译器在内的许多平台上编译软件,这只是需要注意的事情。

于 2008-09-21T00:39:00.797 回答
4

好吧,如果您在接口类中使用指向主力类的指针,并且不将它们作为参数或接口方法中的返回类型公开,则不需要在接口头文件中包含这些工作马的定义(您只需转发声明它们)。这样,您界面的用户就不需要知道后台的类。

您绝对不需要为此嵌套类。事实上,随着项目的发展,单独的类文件实际上会使您的代码更具可读性和更易于管理。如果您需要子类化(例如针对不同的内容/编解码器类型),它也会在以后帮助您。

这是有关PIMPL 模式的更多信息(第 3.1.1 节)。

于 2008-09-25T23:34:32.203 回答
2

仅当您无法使用可能的外部类的公共接口将内部类实现为单独的类时,才应使用内部类。内部类增加了类的大小、复杂性和责任,因此应谨慎使用它们。

您的编码器/解码器类听起来更适合策略模式

于 2008-09-18T15:19:37.250 回答
1

避免嵌套类的一个原因是,如果您打算用 swig ( http://www.swig.org ) 包装代码以与其他语言一起使用。Swig 目前在嵌套类方面存在问题,因此与暴露任何嵌套类的库进行交互变得非常痛苦。

于 2008-09-20T07:37:30.033 回答
1

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

于 2008-09-23T19:07:55.030 回答