如何用非虚拟函数覆盖虚拟函数
How to override a virtual function with a non-virtual function?
请参阅此问题:使用非虚拟覆盖隐藏虚拟功能
这个问题:覆盖非虚拟功能
重写虚拟函数的函数也是虚拟的,即使它没有明确声明为虚拟的。
我的技术问题是:是否有办法使覆盖函数成为非虚拟的(并将其应用于层次结构中较低的类)?换句话说,我可以关闭"虚拟"吗?
显然,我们可以用虚拟函数覆盖非虚拟函数。我们可以做相反的事情吗,即用非虚拟函数覆盖虚拟函数?
您正在寻找一种方法来覆盖虚拟函数,使其不再是虚拟的。
使用继承的可能方法
不幸的是,一旦成员函数被声明为虚拟的,就无法摆脱它的虚拟性。这是C++标准的直接结果:
10.3/2:如果虚拟成员函数vf在基类和直接或间接从基类派生的Derived类中声明,具有相同名称、参数类型列表等的成员函数vf,cv限定符和refqualifier(或不存在相同的)作为Base::vf声明,则Derived::vf也是虚拟的。
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 { // 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
};
类E继承自虚拟和非虚拟。我们只是说,如果有人称之为,就使用非虚拟的
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
请注意,这个技巧仅适用于当前级别:如果您派生了一个类形式E,该类也将间接继承自a,这又是一个虚拟诅咒!
你打算实现什么
使用虚拟函数,您可以确保始终调用与对象的真实标识相对应的适当函数,而不管您使用的是指向基的指针。这就是多态性的目标。
对于非虚拟函数,编译器会根据您访问的类型调用他认为正确的函数。如果您通过有效的基指针访问对象,则它将使用基类的函数,而不是派生的函数。这真的是你想要的吗?
如果是,就这样做:
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.
使用虚拟和非虚拟功能的可能方法
只需很少的额外成本,您就可以在代码中模拟这种行为,使用两个函数的组合:一个是私有虚拟函数,另一个是公共非虚拟函数:
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 :-)
};
C++引入了final
。我没有用过,但这是你的解决方案。该方法仍然是虚拟的,但无法重写。
您想要使用c++11 final
,类似于:
struct A {
virtual void foo();
};
struct B : A {
void foo() final; // virtual overrides A::foo
};
struct C : B {
void foo(); // error: can't override
};
这是我的技术答案否,如果我们不覆盖派生类中的虚拟函数,那么派生类的vitable将包含基类虚拟函数的地址。
- C++无法定义虚拟函数 OUTER 类和头文件
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 当覆盖存在时调用基本虚拟"binded to object"函数
- 如何在C++中伪造虚拟可变参数函数模板?
- 类型擦除的std::function与虚拟函数调用的开销
- 重写虚拟函数和继承
- 是否可以使用函数指针调用虚拟析构函数?
- 在没有动态内存的世界中,我是否需要虚拟析构函数?
- 虚拟继承基构造函数消除
- "虚拟""覆盖"析构函数
- 类中的虚拟布尔函数参数不起作用
- 用纯虚拟函数兜圈子
- 将C++子类成员函数(虚拟实现)传递给 C 类型函数指针
- 尝试在 QLabel 上绘画失败(无法在没有对象的情况下调用成员函数"虚拟无效 QLabel::p aintEvent(QPaintEvent*)")
- 声明析构函数虚拟就足够了吗?
- 视觉 C++当我们在基类中使函数成为纯虚拟时,那么在子类中再次使相同的函数虚拟的必要性是什么
- 重载函数(虚拟/非虚拟)