扩展现有的类,如命名空间(C ++)?

时间:2008-10-23 03:06:22

标签: c++ code-organization

我正在写第二人称只是因为它很容易,对你而言。

您正在使用游戏引擎,并且真的希望特定引擎类有一个新方法“bla”。但是你不希望将“游戏”代码传播到“引擎”代码中。

因此,您可以使用一种新方法从中派生一个新类,并将该代码放在“游戏”源目录中,但也许还有另一种选择?

所以这在C ++语言中可能完全是非法的,但你首先想到的,“也许我可以通过我自己的标题向现有类添加一个新方法,其中包含'parent'标题和一些特殊语法。这是使用命名空间时可能,例如......“

假设您无法跨多个标头声明类的方法(并且您确定不能这样做),那么支持“中间件/引擎/库”和“应用程序”之间清晰划分的其他选项有哪些? ',你想知道吗?

8 个答案:

答案 0 :(得分:8)

我唯一的问题是,“你的附加功能是否需要成为会员功能,还是可以成为免费功能?”如果您想要做的事情可以使用类的现有接口来解决,那么唯一的区别是语法,您应该使用自由函数(如果您认为这是“丑陋的”,那么......吮吸它并继续前进, C ++不是为monkeypatching设计的。)

如果您正试图了解该类的内部内容,则可能表明原始类缺乏灵活性(它没有为您提供足够的信息以便从公共接口执行您想要的操作)。如果是这样的话,也许原来的课程可以“完成”,而你又回到了自由职能的基础上。

如果绝对不会有任何效果,并且你只需要一个成员函数(例如原始类提供了你想要的受保护成员,并且你没有自由修改原始界面)......然后采用继承和成员函数实现。

要进行深入讨论(并解构std::string'),请查看此Guru of the Week "Monolith" class article

答案 1 :(得分:1)

听起来像'行为'关系,不适合继承(谨慎使用!)。

一个选项是组合实用程序类,它通过使用指向它的指针实例化,对“引擎”的某个实例起作用。

答案 2 :(得分:1)

  • 继承(正如您所指出的)或
  • 使用函数代替方法,或
  • 更改引擎代码本身,但使用像quilt或Mercurial / MQ这样的补丁管理器隔离和管理更改

虽然在这种情况下我没有看到继承有什么问题。

答案 3 :(得分:1)

如果新方法将使用现有的公共接口实现,那么可以说它更加面向对象,因为它是一个单独的函数而不是一个方法。至少,斯科特迈耶斯认为它是。

为什么呢?因为它提供了更好的封装。 IIRC的论点是,类接口应该定义对象所做的事情。辅助函数是可以对对象完成的事情,而不是对象必须自己完成的事情。所以他们不属于班上。如果他们在课堂上,他们可以不必要地访问私人成员,从而扩大该成员的隐藏范围,从而扩大私人成员以任何方式改变时需要触摸的代码行数。

当然,如果您想访问受保护的成员,那么您必须继承。如果你想要的方法需要每个实例状态,但不能访问受保护的成员,那么你可以根据品味继承或复合 - 前者通常更简洁,但如果关系不是真的“是一个”,则有一定的缺点

答案 4 :(得分:0)

听起来你想要Ruby mixins。不确定C ++中有什么特别之处。我认为你必须继承。

编辑:您可以将朋友方法放入其中并像混合一样使用它,但我认为您将开始以糟糕的方式打破封装。

答案 5 :(得分:0)

你可以做类似COM的事情,其中​​基类支持QueryInterface()方法,该方法允许你请求一个具有该方法的接口。这在C ++中实现起来相当简单,你本身不需要COM。

你也可以“假装”成为一种更动态的语言,并将一系列回调作为“方法”,然后使用模板或宏调用它们并在其余部分之前将“this”推入堆栈。参数。但这将是疯狂的:))

答案 6 :(得分:0)

Objective C中的类别。

在C ++中有扩展类体系结构(而不​​是单个类)的概念方法,但它不是一种随意的行为,需要提前规划。遗憾。

答案 7 :(得分:0)

听起来像是一个经典的继承问题。除非我将代码放在“引擎增强”目录中。在你的架构中包含这个概念。