是否有任何方法可以使这项工作,因为我认为它可能有效?
你应该覆盖成员函数并显式调用B::start()
:
class C: public A, private B { public: void start() override { B::start(); } };
为什么编译器会接受此代码有效?正如我所看到的,现在有两个
start()
函数在C中具有完全相同的签名,但编译器看起来很好并且只能调用A::start()
.
你是对的,有两个成员函数可以在C(A::start()
和B::start()
)中访问.并且,在class C
没有通过执行a 覆盖start()
或使start()
任何基类可见的情况下using ...::start()
,当尝试使用来自对象的未经验证的namelookup调用成员函数时,将会出现歧义错误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
,它不会覆盖它.要调用make所有上述不合格的成员函数调用,要调用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() }