如何覆盖具有非虚函数的虚函数? [英] How to override a virtual function with a non-virtual function?

查看:124
本文介绍了如何覆盖具有非虚函数的虚函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请参阅此问题:使用非虚拟替换隐藏虚拟函数

a>



这个问题:覆写非虚函数



覆盖虚函数的函数也是虚函数,即使它没有明确声明为虚函数。



我的技术问题是:有没有使覆盖函数非虚拟(并应用于层次较低的类)?换句话说,我可以关闭虚拟吗?



显然,我们可以用虚函数重写非虚函数。我们可以做相反的事,即用非虚函数重写一个虚函数?

解决方案

以覆盖虚拟函数,使得它不再是虚拟的。



使用继承的可能方法



不幸的是,你不能摆脱虚拟的成员函数一旦被声明为虚拟。这是C ++标准的直接后果:


10.3 / 2:如果一个virtual成员函数vf在类Base一个类Derived,直接或间接地派生来自Base,
a成员函数vf具有相同的名称,参数类型列表,
cv-qualification和refqualifier同样),因为Base :: vf是
声明的,则Derived :: vf也是也是virtual


使用 final 不会解决你的问题:它将禁止你覆盖更多派生类中的函数。函数将保持虚拟。



然而,有一个(不方便的)技巧,在一个特定的级别删除虚拟化,使用多重继承:

  class A {
public:
virtual void foo(){cout< A<< endl; }
};
class B:public A {
public:
void foo(){cout< B< endl; }
};
class C:public B {
public:
void foo(){cout<< C< endl; }
};
class EH {//辅助类,不是从A
派生的public://所以foo()是非虚拟的这里
void foo(){cout< EH! << endl; }
};
class E:public B,public EH {//继承虚拟foo和非虚拟的一个
public:
使用EH :: foo; //我们只是说使用非虚拟的
};

类E继承自虚拟和非虚拟。我们只是说如果调用它就使用非虚拟的:

  E e; 
e.foo(); //调用非虚函数EH :: foo(); => EH!
B * pb2 =& e;
pb2-> foo(); //调用原来的虚函数B :: foo()=> B

请注意,此技巧仅适用于当前级别:If你会得到一个类形式E,该类也将从A间接继承,这里是虚拟诅se!



您打算达成什么?



你总是调用对应于你的对象的真正idendity的适当的函数,不管你使用指向一个基地的事实。这就是多态性的目标。



对于非虚函数,编译器调用他认为是正确的函数,根据你访问的类型。如果通过有效的基指针访问对象,它将使用基类的函数而不是派生的基类的函数。这是真的你想要什么?



如果是,只需执行以下操作:

  C c; 
B * pb =& c;
pb-> foo(); //使用虚函数
pb-> B :: foo(); //但是你可以强制使用该函数,忽略虚拟性。

使用虚拟函数和非虚函数的可能方法

无需额外的花费,你可以使用2个函数的组合模拟代码中的这种行为:私有虚拟对象和公共非虚拟对象:

  class A {
virtual void foo2(){cout< A<< endl; } // virtual function
public:
void foo(){foo2(); } //非虚函数调用virtual one
};
class B:public A {
void foo2(){cout< B< endl; } //覆盖virtual
};
class C:public B {
public:
void foo(){cout< C< endl; } //忽略虚拟并覆盖非虚函数:-)
};


Refer to this question: Hide virtual function with non-virtual override

And this question: override on non-virtual functions

A function that overrides a virtual function is virtual too, even though it's not explicitly declared virtual.

My technical question is: Is there away to make that overriding function non-virtual (and applies that to classes lower in the hierarchy)? In other words, can I turn the "virtuality" off?

Obviously we can override a non-virtual function with a virtual function. Can we do the opposite, i.e. to override a virtual function with a non-virtual function?

解决方案

You are looking for a way to overrride a virtual function, so that it is no longer virtual.

Possible approaches using inheritance

Unfortunately, you cannot get rid of the virtuality of the member function once it is declared virtual. This is a direct consequence of the C++ Standard:

10.3/2: 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, parameter-type-list , cv-qualification, and refqualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual.

The use of final will not solve your problem: it will just forbid you to override the function in more derived classes. The function will remain virtual.

There is however an (unconvenient) trick to remove virtualisation at one specific level, using multiple inheritance:

class A {
public:
    virtual void foo() { cout << "A" << endl; }
};
class B : public A {
public:
    void foo() { cout << "B" << endl; }
};
class C : public B { 
public:
    void foo() { cout << "C" << endl; }
};
class EH {   // Helper class, does not derive from A 
public:      // so foo() is non virtual here
    void foo() {   cout << "EH!" << endl; }
};
class E : public B, public EH { // inherits the virtual foo and the non virtual one
public:
    using EH::foo;     // We just say to use the non virtual one
};

The class E inherits from both the virtual and the non virtual. We just say to use the non virtual one if one calls it:

E e; 
e.foo();          // calls the non virtual function EH::foo(); => EH!
B* pb2 = &e; 
pb2->foo();       // calls the original virtual function B::foo() => B

Be aware that this trick works only for the current level: If you'd derive a class form E, the class would also inherit indirectly from A, and here is the virtual curse again !

What do you intend to achieve ?

With virtual functions, you ensure that you always call the appropriate function corresponding to the real idendity of your object, regardless the fact that you use a pointer to a base. That's the goal of polymorphism.

With non-virtual function, your compiler invokes the function he thinks is the correct one, according to the type you are accessing to. If you access the object via a valid base pointer it will hence use the function of the base class instead of the derived one. Is this really what you want ?

if yes, just do this:

C c;
B* pb = &c;
pb->foo();         // uses the virtual function
pb->B::foo();      // but you can force to use the function, ignoring the virtuality.  

Possible approach using a virtual and a non virtual function

With little additional cost you could emulate this behaviour in your code, using a comibnation of 2 functions: a private virtual one, and a public non virtual:

class A {
    virtual void foo2() { cout << "A" << endl; }  // virtual function
public:  
    void foo() { foo2(); } // non virtual function calling the virtual one 
};
class B : public A {
    void foo2() { cout << "B" << endl; }  // overriding virtual
};
class C : public B { 
public:
    void foo() { cout << "C" << endl; }   // ignore the virtual and override the non virtual function :-) 
};

这篇关于如何覆盖具有非虚函数的虚函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆