【发布时间】:2025-12-30 02:25:06
【问题描述】:
我是 C++ 编程的新手,想问一下如何以最有效的方式实现某些东西。假设我有一个 A 类,它有两个函数 foo 和 bar。 Main 将实例化 A 的对象并调用 foo。这个类做了一些计算成本很高的事情,其中 foo 可能会调用 bar ,反之亦然,回溯等等,直到计算出一些结果。我现在想为这个类实现一个装饰器之类的东西,其中功能栏现在与以前一样,但在返回之前,例如打印一些中间结果,同时保持原始实现可用于不需要这些中间结果的情况。其他一切都保持不变。
我想知道我会以最好的方式实现这样的东西。我当然可以在 A 类的 bar 末尾添加一些 if 语句并检查 main 中设置的一些成员变量,但是由于这些函数将被大量调用,这将添加许多实际上不需要的额外检查,如一次检查就足够了。我还可以创建 A 类的副本,我们称它为 B,并在那里修改 bar。但这会复制大部分代码,并且需要对 A 和 B 进行后续更改。我还可以在 A 中创建函数 bar 并让 B 从 A 派生并覆盖它,但是我只需进行这些检查以调度决定的形式,不是吗?
【问题讨论】:
-
我会使用可以配置为开启或关闭的日志库。
-
检查布尔值比通过函数调用间接(这就是你的装饰)要便宜得多。对于布尔检查,机器级别的实现将是对特定内存位置的条件跳转;现代 CPU 的分支预测器早餐吃这个。 – 对于装饰器,必须加载装饰器函数位置,然后跳转或调用该位置,这将加载另一个位置(您的原始函数)并调用它;由于这些功能可能相距甚远,因此分支检测器的工作量要少得多。
-
@John Kugelman:如果仍然必须在运行时决定是否应该打印中间结果,但在 main 中只做一次,这将如何工作?就像,它仍然是一个二进制文件,是否应该进行打印将基于例如程序参数中的标志
-
@datenwolf:我还认为,如果在对象的剩余生命周期中调用第一个 foo 后,条件基本上是固定的,那么跳转预测可能会处理它。我只是想知道是否有一种惯用的方式来做这样的事情
-
除非出现明显的效率问题,否则不要担心效率。您正在尝试执行的操作,可选择打印结果以帮助您了解代码中发生的情况——这正是记录器的用途。使用记录器,然后您可以在要调试此代码时打开日志,并在不想调试时将其关闭。不需要重新发明*,是吗? :)
标签: c++ code-duplication