如果我们创建一个指向基类类的对象指针,该对象指向其子类对象,那么我们使用虚拟关键字进行后期绑定 所以,在后期绑定的情况下,我们的代码如下: -
#include<iostream>
using namespace std;
struct A{
virtual void print() {
cout<<"function1";
}
};
struct B : public A{
void print(){
cout<<"function2";
}
};
struct C : public B{
void print(){
cout<<"function3";
}
};
int main(){
A* a = new C();
A* p = new B();
a->print();
p->print();
}
现在我的问题是:当我们在基类中使用虚拟关键字时,在基类中创建的派生类的所有函数都将变为虚函数。 在多级继承中,有什么办法可以阻止类c的函数被虚拟化? 有什么方法可以打破这个虚拟功能链? 对不起有任何错误,但我尽我所能..☺️☺️
答案 0 :(得分:1)
无法在子类中创建已virtual
不是virtual
的函数。
虚拟性是顶级基类的属性,而不是子类。一旦方法被标记为virtual
,并且指向该类的指针在调用时必须使用该函数的动态调度,因为指针可能指向已覆盖该行为的子类。
考虑以下代码:
A a;
B b;
C c;
A * ap = &a;
A * bp = &b;
A * cp = &c;
ap->print(); // 'function1'
bp->print(); // 'function2'
cp->print(); // 'function3'
这里,对print
的调用不能告诉在编译时调用哪个函数,它们绝对必须使用动态调度。
但是,您可以使C::print
的行为与A::print
struct C : public B {
void print() {
A::print();
}
};
结果是:
ap->print(); // 'function1'
bp->print(); // 'function2'
cp->print(); // 'function1'
如果A::print()
的行为发生变化,C::print()
会反映这些变化。
但是,除非您使用下面列出的final
关键字,否则仍然可以覆盖。
原始回答:
我相信您正在寻找final
说明符。
它仅在C ++ 11中可用。
引用en.cppreference关于final specifier:
的页面在虚函数声明或定义中使用时,最终 确保该函数是虚函数并指定它可能不是 被派生类重写。该计划形成不良(a 否则会生成编译时错误。
他们提供的示例的变体,演示了您的问题的解决方案:
struct A
{
virtual void foo();
};
struct B : A
{
void foo() final; // B::foo is overridden and it is the final override
};
struct C : B
{
void foo() override; // Error: foo cannot be overridden as it's final in B
};