可以,但是要小心。它可能不象你期望的那樣工作。在構(gòu)造函數(shù)中,虛擬調(diào)用機(jī)制不起作用,因?yàn)槔^續(xù)類的重載還沒(méi)有發(fā)生。對(duì)象先從基類被創(chuàng)建,“基類先于繼續(xù)類(base before derived)”。
class D : public B { public: D(const string & ss) :B(ss) { cout << "D constructor/n";} void f(const string& ss) { cout << "D::f/n"; s = ss; } PRivate: string s; };
int main() { D d("Hello"); } 程序編譯以后會(huì)輸出:
B constructor B::f D constructor 注重不是D::f。設(shè)想一下,假如出于不同的規(guī)則,B::B()可以調(diào)用D::f()的話,會(huì)產(chǎn)生什么樣的后果:因?yàn)闃?gòu)造函數(shù)D::D()還沒(méi)有運(yùn)行,D::f()將會(huì)試圖將一個(gè)還沒(méi)有初始化的字符串s賦予它的參數(shù)。結(jié)果很可能是導(dǎo)致立即崩潰。
有人暗示,這只是一條實(shí)現(xiàn)時(shí)的人為制造的規(guī)則。不是這樣的。事實(shí)上,要實(shí)現(xiàn)這種不安全的方法倒是非常輕易的:在構(gòu)造函數(shù)中直接調(diào)用虛擬函數(shù),就象調(diào)用其它函數(shù)一樣。但是,這樣就意味著,任何虛擬函數(shù)都無(wú)法編寫了,因?yàn)樗鼈冃枰揽炕惖墓潭ǖ膭?chuàng)建(invariants established by base classes)。這將會(huì)導(dǎo)致一片混亂。