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