有沒有什麼辦法讓這項工作,因爲我認爲它可能已經工作?
你應該重寫成員函數和顯式調用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