B 类重写了 A 类的纯虚函数“print()”。C 类继承了 B 类并具有“using A::print”语句。
那么为什么 C 类不是抽象类呢?
class A {
public :
virtual void print() =0;
};
class B:public A {
public:
void print();
};
void B :: print() {
cout << "\nClass B print ()";
}
class C : public B {
public:
using A::print;
};
void funca (A *a) {
// a->print(1);
}
void funcb (B *b) {
b->print();
}
void funcc (C *c) {
c->print();
}
int main() {
B b;
C c;
funca(&c);
funcb(&c);
funcc(&c);
return 0;
}
Output:
Class B print ()
Class B print ()
根据我第一次尝试寻找答案、@Oliv 的评论和答案,让我尝试总结所有可能的情况using A::memberFct
里面声明C
.
-
A
的成员函数是虚拟的并且被覆盖B
-
A
的成员函数是非虚拟的并且被隐藏B
-
A
的成员函数是非虚拟的并且被隐藏C
itself
这些情况的一个小例子如下。
struct A {
virtual void f() {}
void g() {}
void h() {}
};
struct B : A {
void f() override {}
void g() {}
};
struct C : B {
using A::f; // Virtual function, vtable decides which one is called
using A::g; // A::g was hidden by B::g, but now brought to foreground
using A::h; // A::h is still hidden by C's own implementation
void h() {}
};
通过调用所有三个函数C
的接口导致不同的函数调用:
C{}.f(); // calls B::f through vtable
C{}.g(); // calls A::g because of using declarative
C{}.h(); // calls C::h, which has priority over A::h
请注意,在类内部使用声明的影响有限,即它们更改名称查找,但不会更改虚拟调度(第一种情况)。成员函数是否是纯虚函数都不会改变此行为。当基类函数被继承层次结构中的函数隐藏时(第二种情况),查找将被调整,以便受 using 声明约束的函数具有优先权。当基类函数被类本身的函数隐藏时(第三种情况),类本身的实现具有优先级,请参见参考参数 https://en.cppreference.com/w/cpp/language/using_declaration:
如果派生类已具有具有相同名称、参数列表和限定条件的成员,则派生类成员将隐藏或覆盖(不与)从基类引入的成员。
在你的原始片段中,C
因此不是一个抽象类,因为只有相关成员函数的查找机制受 using 声明的影响,并且 vtable 点并不指向纯虚拟成员函数实现。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)