【发布时间】:2023-04-01 15:58:02
【问题描述】:
我从事 C++ 工作多年,但没有接受过正规培训。我的大部分背景是航空航天,我们必须总是重新发明轮子,不使用 3rd 方库或 API,所以这些对我来说有点新。
我正在开发一些具有 API 的东西,但我对一些现有代码感到有些困惑。问同事时,他们也没有任何答案。
我有一个继承 API 的 Application 类的类。这个Application 类有一个名为onUpdate() 的受保护虚函数,描述为:
更新逻辑的回调函数,每帧调用一次
class MyApp : public Application {
public:
virtual void onUpdate() override;
}
void MyApp::onUpdate() {
Application::onUpdate(); // Why do this?
...
}
首先,我认为回调中应该包含某种函数指针 lambda 等。
有人提到的唯一答案是,这是一个“典型”的事情,以便调用可能不同的 Application::onUpdate() 函数。但是如果有基类实现,声明一个虚函数不会覆盖吗?
我原以为如果有必要,文档会说“如果您选择自己编写,请务必调用基类 onUpdate 函数”。
我在通话中尝试了一个断点,它似乎什么也没做。我想知道编译器是否正在优化它,甚至认为我有-O0。我可以删除它,代码看起来运行得很好,但它相当复杂,所以我不想造成一些下游问题。
我什至不确定要搜索什么。我似乎找不到类似的例子。这个实现有正式的名字吗?我无法将我的大脑包裹在这个问题上。
【问题讨论】:
-
既然您从
Application派生一个新类,大概有一种方法可以让您使用API 注册您的类,以便它知道实际使用它。然后大概在 API 内部的某个地方,通过指向您的类的实例的Application*指针对onUpdate()进行了调用,从而通过虚拟调度调用了覆盖的onUpdate()。这是覆盖onUpdate()的唯一方法。 -
大概,这段代码的作者想要保护自己,以防派生类可能需要/受益的某些功能被添加到
Application::onUpdate。这是防御性编程的一个例子,尽管在这种情况下可能没有必要。 -
没有 Application* 指针。派生类有几个函数作为线程产生,这些线程通过 while 循环和 this_thread::sleep() 函数保持活动状态。这一切对我来说都很奇怪。在派生的 onUpdate 函数中的调用堆栈只是说外部代码,所以我假设库代码隐藏了一些东西。
-
我没有看到任何注册类的调用,而且 API 似乎没有提供任何“注册”功能。我不想这么说,但它只是“神奇地”起作用,这也让我很困扰。
-
@brettgrant99
Application的onUpdate成员函数是纯虚函数吗?如果不是,该函数仍然退出。也许在你的代码执行之前必须先执行某种复杂的初始化代码
标签: c++ inheritance