我的API应该使用非成员函数来作用于对象,还是使函数成为对象的公共函数?

时间:2010-09-24 07:35:05

标签: c++ api oop

最近我了解到OOP的许多好处(包括漂亮的代码)。

所以,现在我正在尝试为个人使用编写一个小型物理API,也许是为了放入一些小游戏。这主要是因为我喜欢练习编码,我喜欢我的物理。

但问题是,许多API都有这样的界面(包括Windows API):

// In this case, Object is just a plain data container without a constructor.
Object object = NewObject(...);
DoSomething(object);
DoAnotherThing(object,...);
 ... and so on

这是应该安排的方式,还是有更多OO风格的方式,例如:

Object object(...);
object.DoSomething(...);
object.DoAnother(otherObj,...);
otherObject.attachNode(object);
 ... and so on again

我希望你明白这个主意。因此,总结一下问题,哪个方法更受欢迎,为什么我看到了很多第一个例子,尽管OOP得到了美化(尽管参考中的这些API可能只是旧的,比如Windows API)。 p>

作为旁注,您如何看待Windows API?对我来说似乎有点......不对。

8 个答案:

答案 0 :(得分:5)

API可以按您想要的任何方式查找。如果要创建C ++ API,则可以根据需要使用成员函数。使用Win32 API,Microsoft必须制作可从C(以及各种其他语言)以及C ++访问的内容,因此他们必须使用普遍可访问的功能来表达所有内容。这意味着他们不能使用类(或扩展名,成员函数),名称空间,重载,模板和各种其他C ++特性。

然后他们采用了相当合理的前提,并构建了可以想象的最丑陋,最不一致的API。

如果您的API旨在从C ++代码中使用,那么您可以使用您喜欢的所有C ++功能。

另一方面,即使在C ++中,使一切成为一个成员函数也不一定是可取的。 默认情况下,使用非成员函数可以是a very good idea,即使在面向对象的代码中也是如此,尽管原因与Microsoft在其API中的原因不同。

答案 1 :(得分:2)

面向对象编程的一个支柱是封装。因为尽可能少的代码应该依赖于对象的内部,因为这些内部可能会发生变化。成员函数可以访问那些内部,非成员(非朋友)函数不能。

这意味着do_something(object)实际上更多OO 而不是object.do_something(),并且许多OO官员似乎根本没有这样做。

当然这是过于简单化了。如果需要动态分派,则必须使用成员函数。有关详细信息,请参阅有效C ++中的第23项或单击How Non-Member Functions Improve Encapsulation

答案 2 :(得分:1)

我认为这是一个非常主观的话题。

虽然我倾向于选择object.DoSomething()风格,但我认为其他方式并没有错。我甚至会说,有时,它更有意义。

我相信真正重要的是您的API保持一致。

通常情况下,当所选样式不合适时,您会注意到它,因为有些事情似乎不对。

答案 3 :(得分:1)

这取决于您是否希望API与OO和非OO代码一起使用。您的示例Windows API旨在主要(至少在最初)使用非OO代码。因此,如果您确定您的用户仅使用OO语言(特别是如果它仅适用于您自己的项目),请坚持使用您正在使用的语言的任何内容。所以对于C ++,我会选择第二个选项,并充分利用语言的功能。

答案 4 :(得分:1)

该文件可能不是100%适合该问题,但仍然密切相关。 Scott Meyers讨论了问题中提到的两种风格。 Scott Meyers: How Non-Member Functions Improve Encapsulation

答案 5 :(得分:0)

前一个系统是C类的。后者是OO的做事方式。

答案 6 :(得分:0)

如果您没有受某些性能限制的约束,请使用对象方法。在这种情况下,方法的选择是有限的,并且在C风格中,您可以选择所有可能的方法。人类记忆是有限的,所以将所有东西分成小的(和可测试的!)部分。

答案 7 :(得分:0)

你不应该将拼写与设计混为一谈。

object.Foo()只是一种拼写方式,表示你在对象上调用Foo方法。另一种OO语言可以使用拼写CallMethod(object, Foo)来表示完全相同。或者它可以使用Foo(object)语法。

现在,Windows API是一种旨在供OO和非OO语言使用的API。您似乎正在使用Windows API的C绑定,即从#include <windows.h>获得的绑定。 C根本不是OO。因此,从{+ C ++的角度来看,windows.h似乎不像是OO API。