gpt4 book ai didi

C++ 我应该使用虚拟方法吗?

转载 作者:太空狗 更新时间:2023-10-29 20:41:26 24 4
gpt4 key购买 nike

首先让我说明我了解虚拟方法的工作原理(多态性、后期绑定(bind)、vtables)。

我的问题是我是否应该使我的方法成为虚拟方法。我将在具体案例中举例说明我的困境,但也欢迎任何一般性指导方针。

上下文:

我正在创建一个库。在这个库中,我有一个 CallStack 类,它捕获调用堆栈,然后提供对捕获的堆栈帧的类似 vector 的访问。捕获由 protected 方法 CaptureStack 完成。如果库的用户希望实现另一种捕获堆栈的方法,则可以在派生类中重新定义此方法。需要明确的是,使方法 virtual 的讨论仅适用于我知道可以在派生类中重新定义的一些方法(在本例中为 CaptureStack析构函数),而不是所有的类方法。

在我的整个库中,我使用 CallStack 对象,但从未公开为指针或引用参数,因此仅考虑使用我的库时就不需要 virtual

而且我想不出有人想要使用 CallStack 作为指针或引用来实现多态性的情况。如果有人想派生 CallStack 并重新定义 CaptureStack 我认为只使用派生类对象就足够了。

现在只是因为我认为不需要多态性,所以我应该不使用 virtual 方法,还是应该使用 virtual 而不管只是因为可以重新定义方法。


CallStack 如何在我的库之外使用的示例:

if (error) {
CallStack call_stack; // the constructor calls CaptureStack
for (const auto &stack_frame : call_stack) {
cout << stack_frame << endl;
}
}

重新定义 CaptureStack 的派生类可以以相同的方式使用,不需要多态性:

if (error) {
// since this is not a CallStack pointer / reference, virtual would not be needed.
DerivedCallStack d_call_stack;
for (const auto &stack_frame : d_call_stack) {
cout << stack_frame << endl;
}
}

最佳答案

如果您的库在构造函数期间保存调用堆栈,那么您不能使用虚拟方法。

这是 C++。当从另一种语言转向 C++ 时,人们经常犯的一件事是在构造函数中使用虚方法。这永远不会按计划进行。

C++ 在每次构造函数调用期间设置虚函数表。这意味着当从构造函数调用时,函数从不是虚拟的。虚方法总是指向当前正在构造的类。

因此,即使您确实使用虚方法来捕获堆栈,构造函数代码也始终会调用基类方法。

要让它工作,你需要从构造函数中取出调用并使用类似的东西:

CallStack *stack = new DerivedStack;
stack.CaptureStack();

您的代码示例都没有显示将 CaptureStack 虚拟化的充分理由。

关于C++ 我应该使用虚拟方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21378077/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com