有什么方法可以使这项工作像我认为的那样有效吗?
您应该覆盖成员函数并显式调用B::start()
:
class C: public A, private B {
public:
void start() override { B::start(); }
};
为什么编译器会接受此代码为有效的?正如我所看到的,现在有两个start()
函数在 C 中具有完全相同的签名,但编译器似乎很好,只调用A::start()
.
A::start()
你是对的,在 C (和B::start()
)中有两个可访问的成员函数。并且在class C
不覆盖start()
或start()
通过执行 a 使任何基类可见的情况下using ...::start()
,尝试使用来自 的对象的未限定名称查找来调用成员函数时,您将遇到歧义错误C
。
class A {
public:
virtual void start() { std::cout << "From A\n"; }
};
class B {
public:
void start() { std::cout << "From B\n"; }
};
class C: public A, private B {
};
int main(){
A* a = new C();
a->start(); //Ok, calls A::start()
C* c = new C();
c->start(); //Error, ambiguous
}
要解决此问题,您必须使用限定名称,例如:
C* c = new C();
c->A::start(); //Ok, calls A::start()
现在using B::start()
,class C
只要从start()
_B::start()
C
class A {
public:
virtual void start() { std::cout << "From A\n"; }
};
class B {
public:
void start() { std::cout << "From B\n"; }
};
class C: public A, private B {
public:
using B::start();
};
int main(){
A* a = new C();
a->start(); //Ok, calls A::start()
C* c = new C();
c->start(); //Ok, calls B::start()
}
using B::start
使函数void B::start()
在 中可见C
,它不会覆盖它。调用使上述所有不合格的成员函数调用,调用B::start()
,你应该重写成员函数C
,并使其调用B::start()
class A {
public:
virtual void start() { std::cout << "From A\n"; }
};
class B {
public:
void start() { std::cout << "From B\n"; }
};
class C: public A, private B {
public:
void start() override { B::start(); }
};
int main(){
A* a = new C();
a->start(); //Ok, calls C::start() which in turn calls B::start()
// ^^^^^^^^^^^^^^^^ - by virtual dispatch
C* c = new C();
c->start(); //Ok, calls C::start() which in turn calls B::start()
}