【问题标题】:Different functions?不同的功能?
【发布时间】:2024-01-20 10:35:01
【问题描述】:

所以这里是代码示例。任务是提供此代码将打印出来的输出。是2个不同的功能吗?那么 B 类中的 vtable 会发生什么? 它是否仅在 2 个同名的不同函数上存储 2 个指针?

#include<iostream>
#include <vector>
using namespace std;
class A
{
public:
    A()
    {
        init();
    }
    virtual void init(bool a = true)
    {
        if(a)
            cout << "A" << endl;
    }
};
class B :public A
{
public:
    virtual void init()
    {
        cout << "B" << endl;
    }
};

int main()
{
    B b;
    A* a = &b;
    a->init();
    a->init(true);
    system("pause");
}

实在找不到在哪里阅读有关此案例的信息。如果你看过这个案例,你能解释一下或给出一些来源的链接吗?

【问题讨论】:

  • 尝试在启用警告的情况下编译它 - 你应该至少会收到一个有用的警告,这会给你一些洞察力......
  • 哦,clang 显然更有帮助...&lt;stdin&gt;:21:18: warning: 'B::init' hides overloaded virtual function [-Woverloaded-virtual] virtual void init() ^ &lt;stdin&gt;:12:18: note: hidden overloaded virtual function 'A::init' declared here: different number of parameters (1 vs 0) virtual void init(bool a = true)
  • 这就是override的原因。
  • 您编写的每个函数都与其他函数不同。真正的问题是“当我拨打电话时,会选择哪一个?”
  • @PaulR gcc 会在您明确添加您在 clang 警告消息中显示的 -Woverloaded-virtual 开关时发出警告。

标签: c++ overriding signature virtual-functions default-arguments


【解决方案1】:

它们已经是两个不同的函数(覆盖不会改变这一点),但由于它们具有不同的签名,B 中的函数不会覆盖A 中的函数。

请记住,函数的名称只是其身份的一部分!它的参数列表也很重要。

如果您将override 关键字放在B::init() 上,那么您的程序将无法编译,因为B::init() 实际上并没有覆盖任何东西(在它的基础中没有init(),无论是虚拟的还是其他的)。

如果这两个函数实际上具有不同的名称,例如 A::init(bool)B::urgleburgleboop(),则 vtable 不会真正“发生”任何事情。

请注意,除了virtual 和多态性和覆盖之外,B::init() 还“隐藏”A::init(bool) 以实现正常的重载解决方案(感谢 C++!),因此 Clang 会警告您的代码。

至于你可以在哪里阅读它,your C++ book 将是一个好的开始。 :)

【讨论】:

  • 很好的答案,我正在使用nm 写一个,并表明这两种方法签名的损坏符号不同,但理论就足够了。
最近更新 更多