计算科学家应该使用哪些现代 OOP 功能?

计算科学 图书馆 C++ 编程范式
2021-12-10 21:06:30

我认识的许多计算科学家,包括我自己,都不是计算机科学家因此,他们通常不太了解 OOP 中更高级的技术。另一方面,大多数高级程序员都不是计算科学家。在编写科学计算软件时,他们可能不太清楚哪些 OOP 特性是必不可少的或相关的。

主要考虑C++(但也可能是一般情况下),您认为哪些 OOP 功能在数字运算软件中是绝对必要的,为什么?您认为哪些功能通常被认为是好的,但可能会导致不必要的开销?当谈到使用更高级功能的开销时,有哪些“神话”?

我通常喜欢听到以下内容:

1 - 模板

2 - 虚函数

3 - 智能指针和垃圾收集器

[编辑:] 4 - 运算符重载

5 - Boost 库(技术上不是 OOP 功能,但非常流行的C++库)

3个回答

我一般不是 OOP 的大用户,这有其原因。我对您提到的一些功能的看法:

  • 模板:当他们工作时很方便,当他们不工作时调试是一场巨大的噩梦。此外,您并不真正知道“幕后”发生了什么,这可能是错误或效率低下的根源。
  • 虚函数:可以非常方便和优雅,但请记住调用该函数比调用静态函数更昂贵。不要在大计算的最内层循环中使用这些东西。
  • 智能指针:与虚函数一样,在分配和取消引用时要注意隐藏的开销。不要在代码的性能关键部分使用。
  • 垃圾收集器:不一定是 OOP 功能(例如Boehm GC),但仍然是一个很棒的东西。同样,这可能会导致您的程序在清理内存时暂停和等待,但是无论如何您都应该避免在性能关键部分中过度创建/分配和销毁/释放对象,对吗?

您遗漏的一件事是运算符重载,这是一种以可读方式表达事物的极其方便的方式。不过,请再次注意紧密循环中的开销,并记住,一般情况下,编译器将无法优化任何东西(想想常见的子表达式消除、寄存器变量等)。一个很好的替代方案是表达式模板,但编写自己的代码会增加代码复杂性并给你带来奇怪的错误,想想和常规模板一样的混乱

话虽如此,使用其他人的模板,假设它们经过试验和测试并且大部分没有错误,可以让生活变得更加甜蜜。但请记住:can,并非总是如此。

总之,这是一个性能/优雅的权衡。对于用户界面和/或代码的“大图”部分,我肯定会推荐 OOP 或任何类似的东西。但是,由于隐藏的开销以及编译器通常无法进行太多优化的事实,我会在内核或任何对性能至关重要的东西中远离它。

我认为对于开始编程的科学家来说,最重要的一课是“你正在努力解决的编程问题很有可能已经被计算机科学家解决了”。

我想在这里参考“设计模式”:对象之间的许多典型交互、它们的行为等,在有限数量的模式中得到了很好的捕捉,这些模式在许多 OO 编程语言(如 C++、Java、Python、 ...

设计模式的参考是“The Gang-of-Four”(通常称为 GoF)的Design Patterns 。它是完整的,但晚上喝一杯酒并不容易阅读。一个更多的教程方法是Head First Design Patterns,我可以推荐它。

因此,在开始编程工作时,首先进行 OOP 分析(识别对象、行为、关系),然后识别模式并使用它们的参考实现来实现这些。

在 C++ 中“过度”使用模板会导致巨大的编译错误,并可能导致非计算机科学家的挫败感。但是,以表达式模板的形式,它可以显着加快您的代码速度,这是您应该注意的。