在 C++ 中,如果函数重写了虚函数,它是否自动成为虚函数?

发布于 2024-08-04 04:42:12 字数 779 浏览 3 评论 0原文

我希望如果 foo 在类 D 中声明,但未标记为 virtual,那么以下代码将调用 foo 中的实现code>D(无论 d 的动态类型如何)。

D& d = ...;
d.foo();

然而,在下面的程序中,情况并非如此。谁能解释一下吗?如果一个方法重写了虚函数,它会自动成为虚拟方法吗?

#include <iostream>

using namespace std;

class C {
public:
        virtual void foo() { cout << "C" << endl; }
};

class D : public C {
public:
        void foo() { cout << "D" << endl; }
};

class E : public D {
public:
        void foo() { cout << "E" << endl; }
};

int main(int argc, char **argv)
{
        E& e = *new E;
        D& d = *static_cast<D*>(&e);
        d.foo();
        return 0;
}

上述程序的输出是:

E

I would expect that if foo is declared in class D, but not marked virtual, then the following code would call the implementation of foo in D (regardless of the dynamic type of d).

D& d = ...;
d.foo();

However, in the following program, that is not the case. Can anyone explain this? Is a method automatically virtual if it overrides a virtual function?

#include <iostream>

using namespace std;

class C {
public:
        virtual void foo() { cout << "C" << endl; }
};

class D : public C {
public:
        void foo() { cout << "D" << endl; }
};

class E : public D {
public:
        void foo() { cout << "E" << endl; }
};

int main(int argc, char **argv)
{
        E& e = *new E;
        D& d = *static_cast<D*>(&e);
        d.foo();
        return 0;
}

The output of the above program is:

E

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

背叛残局 2024-08-11 04:42:12

标准 10.3.2 (class.virtual) 说:

如果在类 Base 和直接或间接从 Base 派生的类 Derived 中声明了一个虚成员函数 vf,则声明了一个与 Base::vf 具有相同名称和相同参数列表的成员函数 vf,则 Derived ::vf 也是虚拟的(无论是否如此声明)并且它会覆盖*

[脚注:与虚函数具有相同名称但不同参数列表(子句 over)的函数不一定是虚函数,也不会重写。在重写函数的声明中使用虚拟说明符是合法的,但是多余的(具有空语义)。在确定覆盖时不考虑访问控制(子句 class.access)。 --- 脚注结束]

Standard 10.3.2 (class.virtual) says:

If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name and same parameter list as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides*

[Footnote: A function with the same name but a different parameter list (clause over) as a virtual function is not necessarily virtual and does not override. The use of the virtual specifier in the declaration of an overriding function is legal but redundant (has empty semantics). Access control (clause class.access) is not considered in determining overriding. --- end foonote]

梦罢 2024-08-11 04:42:12

快速回答可能是否定的,但正确的答案是

C++ 不知道函数隐藏,因此覆盖没有 virtual 关键字的虚函数也标记该函数为虚函数。

Quick answer may be no, but correct answer is yes

C++ doesn't know about function hiding, so overriding virtual function without virtual keyword marks that function virtual too.

习惯成性 2024-08-11 04:42:12

您没有创建 e 对象的任何副本并将其放入 d 中。因此 d.foo() 遵循正常的多态行为并调用派生类方法。在基类中声明为虚拟的方法在派生类中也自动变为虚拟。

You are not creating any copy of the object of e and putting it in d. So d.foo() follows normal polymorphic behavior and calls derived class method. A method which is declared as virtual in the base class becomes automatically virtual in the derived class also.

羅雙樹 2024-08-11 04:42:12

输出(“E”)的行为与人们所期望的完全一样。

原因:
该引用的动态(即运行时)类型是 E。您正在对 D 进行静态向上转换,但这当然不会改变对象的实际类型。

这就是虚拟方法和动态调度背后的理念:您可以看到正在实例化的类型的行为,在本例中为 E。

The output ("E") behaves exactly as one would expect it to behave.

The reason:
The dynamic (i.e. runtime) type of that reference is E. You are doing a static upcast to D, but that does not change the actual type of the object of course.

That's the very idea behind virtual methods and dynamic dispatches: You see the behavior of the type you were instantiating, which is E, in this case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文