在C++中,我的问题关于:基类有同名成员引起的二义性 这个知识点

2025-02-22 13:45:05
推荐回答(4个)
回答1:

我来试着回答一下,大家看看是不是这样:
1.原本语句打印“在A1中”;这个应该不用解释,这个时候只有A1中存在print方法。
2.增加A2::print()函数后,由于A2继承A1所以A2::print()函数覆盖(overwritten)A1::print()函数,所以这种情况下,对于A2及A2的所有子类的实例来说A1::print函数均是不可见的,所以这里会打印“在A2中”
3.增加B1::print()函数后,B1::print又覆盖了A2::print(),原理和第2条一样,所以结果就是“在B1中”
4.增加B2::print()函数后,由于C同时继承了B1和B2,所以B1::print和B2::print在这里产生了冲突,系统不知道应该调用B1::print还是B2::print,所以程序无法编译通过。
5.增加C::print函数后,调用c1.print结果非常明显,就是调用C::print,这样就消除了第4条中的二义性,所以又可以编译通过了。

你程序中使用的虚基类并不能处理由B1和B2带来的冲突,仅能处理由B1和B2的公共基类A2所带来的冲突,当然这个程序中使用虚基类还是合理的。

回答2:

子类可以调用它的所有祖先的公有函数,如果它的祖先有重名的函数,那么它使用离它最近的祖先的版本。如果它自己也定义了这个函数,则使用自己的版本。所以,你先只在A1中有print函数,那么C使用的就是A1的版本。接着你在A2中定义了,他比A1更接近C,将使用A2的版本。接着在B1中定义,将使用B1的版本。如果你在B2中也定义了,那么B1和B2是同等接近C的,程序将不知道你要使用的是那个版本的。最后在C中也定义了,那么就会直接使用C的版本,不会查找祖先中是否有这个函数,就不会报错了。

回答3:

C直接继承两个父类B1,B2,这两个里面都有print方法
所以不添加语句4的时候调c1.print();程序不知道你到底要调用B1里的还是B2里的,会报错,如果不进行调用,程序可正常编译。
继承的方法,如果有相同的函数,子类总是调用他父类中的那个函数,至于它父类的父类中的同名方法,他不去关心。

回答4:

避免二义性的方法可以采用虚基类