c++ - 一旦函数名称被声明为 'virtual' ,它是否可以再次变为非虚拟的?

标签 c++ virtual

假设我有一些类链,其中每个类都派生自它之前的类。无论出于何种原因,他们都喜欢对某些成员函数使用相同的名称。有点像这样:

class C1 { public:             void f() { cout<<"C1"; }; };
class C2 : public C1 { public: void f() { cout<<"C2"; }; };
class C3 : public C2 { public: void f() { cout<<"C3"; }; };

显然,如果我只声明一些对象,然后从它们调用函数 f,所有对象都会调用与其各自对象类型关联的函数:

C1 c1; c1.f(); // prints C1
C2 c2; c2.f(); // prints C2
C3 c3; c3.f(); // prints C3

现在,如果我声明一些指向对象的指针,然后从它们调用函数 f,所有对象都将调用与它们各自的指针类型关联的函数:

C1* p1 = &c1; p1->f(); // prints C1
C1* p2 = &c2; p2->f(); // prints C1
C1* p3 = &c3; p3->f(); // prints C1
C2* p4 = &c2; p4->f(); // prints C2
C2* p5 = &c3; p5->f(); // prints C2
C3* p6 = &c3; p6->f(); // prints C3

这一切都很棒。我要么调用与对象类型关联的函数,要么调用与指针类型关联的函数...

当然,我可以将函数设为“虚拟”。然后,如果我从某个对象调用该函数,我的行为将不会发生任何变化;但是,如果我从某个指针调用函数,那么我不会只调用指针类型的函数,我实际上会调用指针指向的对象类型的函数。到目前为止一切顺利。

我什至可以通过继承链在中途更改为虚拟。假设我在类 C2 中的函数 f 之前放置了一个虚函数。现在这个函数已经变成了虚拟的(即当从指针调用时,它使用对象指向类型而不是指针类型来解析函数调用),不仅对于它自己的类,而且对于所有 future 的类是从它派生的。

我的问题是:一旦一个函数被声明为虚函数(在继承链中的某个点),它是否可以恢复为非虚函数(在继承链的下游)?

澄清一下:当我说恢复到非虚拟行为时,我的意思是当我从指针调用函数时,它将使用指针的类型来解析函数调用(而不是指针指向的对象类型)指向)。

最佳答案

Once a function has been declared virtual (at some point in the chain of inheritance) can it ever be reverted back to being non-virtual (further down the chain of inheritance)?

没有。一旦函数签名在继承线上的某处被设为虚拟,它将保持这种状态:派生类中具有相同签名的每个函数也将是虚拟 .

解决这个问题的一种方法是使用(滥用?)template method pattern :

struct Base {
    virtual void doFoo() { bar(); }
    void foo() { doFoo(); }
};

struct Derived1 : public Base {
    virtual void doFoo() { baz(); }  // "overrides" foo via doFoo
};

struct Derived2 : public Base {
    void foo() { quux(); }  // "un-virtualize" foo by decoupling it from doFoo
};

在这个继承树中,指针类型将决定调用哪个foo;如果它是来自 Base 的对象,则指向对象的类型将决定调用哪个 doFoo

关于c++ - 一旦函数名称被声明为 'virtual' ,它是否可以再次变为非虚拟的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6866277/

相关文章:

c# - 什么是虚拟方法?

c++ - std::sort 并不总是调用 std::swap

c++ - FreeRTOS任务不应返回-ESP32

c++ - 类派生形式结构上的虚函数

Linux通过snmp访问多个虚拟接口(interface)

C++ - 条件虚函数

c++ - 与 iOS 项目上的 C++ 库链接失败

c++ - infix postfix conversion c++, 好像得不到正确答案

c++ - 在 "Effective Modern C++"示例中在索引运算符之前使用 std::forward 的原因

C++ Virtual boost::any 继承