最近我了解到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?对我来说似乎有点......不对。
答案 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。