有什么方法可以使这项工作像我认为的那样有效吗?
您应该覆盖成员函数并显式调用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()
}