在询问之前,我曾参考过这个older question。但我仍然有疑问。
struct B1 {
virtual void fun () = 0;
};
struct B2 {
void fun () { cout<<"B2::fun()\n"; }
void fun (int i) {}
};
struct D : B1, B2 {
using B2::fun; // This line doesn't help
};
int main ()
{
B1 *pB1 = new D; // Error: cannot allocate 'D' because 'B1::fun()' is abstract
pB1->fun();
}
pure virtual
机制的任何原因?using
关键字无法帮助解决此错误? (编译器:linux-64 g ++)using
关键字,B2::fun()
或B2::fun(int)
使用了哪个功能? (该行没有歧义)答案 0 :(得分:2)
using B2::fun;
只允许您使用B2::fun
方法,但由于B1
是一个抽象类,您必须实现纯虚函数的乐趣该类能够创建其对象。
答案 1 :(得分:0)
确定。我得到了第一个答案,只是基于逻辑推理。假设,标准是接受继承的方法来解决pure virtual
机制,那么正常的“虚拟”函数会有歧义。
即。假设B1::fun()
是正常的虚函数,那么B1::fun()
和B2::fun()
之间会出现选择混淆。因此,最好避免至少考虑virtual
机制的继承成员。
答案 2 :(得分:0)
using
仅调整名称查找过程。它不会将函数导入给定范围,也不会定义新函数。
因此,您只需要定义一个新的virtual
覆盖。
答案 3 :(得分:0)
我绝不是C ++专家程序员,但让我试一试:
我认为从编译器的角度来看,B1和B2是两个完全不同的类,它们碰巧在每个类中都有一个相同名称的方法。即使涉及D的范围,编译器也没有理由使用B2的fun()实现来实现B1的fun()。 (如果我们查看虚拟表机制,我可能会得到一些清楚的东西。我们可能会看到为什么B2 :: fun()对B1的fun()没有帮助。)
“使用”指令只是使符号“有趣”在D的范围内可见。 “using”不会将任何fun()实现附加到D类(但D需要B1 :: fun()的实现)。
嗯......这里的“使用”指令实际上并没有“使用”(或者我们说“调用”)两者之一。 “使用”只是将名称引入D的范围(AKA使名称在D范围内可见,类似于再次声明它们)。
答案 4 :(得分:0)
哪个函数用于使用关键字,B2 :: fun()或B2 :: fun(int)? (没有 暧昧 那条线)
来自ISO / IEC 14882:2003(E)7.3.3.12
当using声明将基类中的名称带入派生类作用域时,派生类中的成员函数会覆盖和/或隐藏基类中具有相同名称和参数类型的成员函数(而不是冲突)。
[Example:
struct B {
virtual void f(int);
virtual void f(char);
void g(int);
void h(int);
};
struct D : B {
using B::f;
void f(int); // OK: D::f(int) overrides B::f(int);
using B::g;
void g(char); // OK
using B::h;
void h(int); // OK: D::h(int) hides B::h(int)
};
void k(D* p) {
p->f(1); //calls D::f(int)
p->f(’a’); //calls B::f(char) // Notice the call being resolved
p->g(1); //calls B::g(int)
p->g(’a’); //calls D::g(char)
}
— end example]
[注意:两个using声明可能会引入函数 相同的名称和相同的参数类型。如果,对于不合格的电话 函数名,函数重载决策选择引入的函数 通过这样的使用声明,函数调用是不正确的。 ]
因此,在您提供的示例中,根本没有歧义。根据传递的参数,可以决定对方法的调用。