有没有什么办法让这项工作,因为我认为它可能已经工作?
你应该重写成员函数和显式调用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
中,如果没有重写start()
或通过执行using ...::start()
使任何基类的start()
可见,则在尝试使用来自C
的对象的unqauified namelookup调用成员函数时会出现模糊性错误。
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()
现在,做一个在class C
using B::start()
仅仅声明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()
}
目前尚不清楚你期待什么。 'C c; c.start();'应该调用'B :: start()'。 – ZDF
这是在这里工作:http://ideone.com/e71lnB – Rama
@拉马我想这是关于A * a =&c; A->开始();为您的ideone示例 – grek40