為什麼建構函式不能夠使虛擬函式
虛擬函式可謂是C++與其它的面嚮物件語言最大的區別了。虛擬函式的存在使為了多型,Java當然也有多型。不過實現方式並不是通過虛擬函式,我們這裡就不做介紹了。
虛擬函式的作用主要是為了繼承的時候,子類通過繼承虛擬函式的介面,而實現子類自定義的函式介面,我們通過虛擬函式表的方式尋找到子類對應的介面。從而實現,一個介面多種實現方式的多型功能。
那麼,有一個問題,建構函式是否能夠設定為虛擬函式?答案是否定的。但是為什麼呢?建構函式之所以不能設定成虛擬函式,主要有以下的幾個原因。下面分別闡述一下。
1.虛擬函式的作用是什麼?是實現部分或預設的功能,而且該功能可以被子類所修改。如果父類的建構函式設定成虛擬函式,那麼子類的建構函式會直接覆蓋掉父類的建構函式。而父類的建構函式就失去了一些初始化的功能。這與子類的構造需要先完成父類的構造的流程相違背了。而這個後果會相當嚴重。
2.虛擬函式的呼叫是需要通過“虛擬函式表”來進行的,而虛擬函式表也需要在物件例項化之後才能夠進行呼叫。在構造物件的過程中,還沒有為“虛擬函式表”分配記憶體。所以,這個呼叫也是違背先例項化後呼叫的準則。
3.虛擬函式的呼叫是由父類指標進行完成的,而物件的構造則是由編譯器完成的,由於在建立一個物件的過程中,涉及到資源的建立,型別的確定,而這些是無法在執行過程中確定的,需要在編譯的過程中就確定下來。而多型是在執行過程中體現出來的,所以是不能夠通過虛擬函式來建立建構函式的,與例項化的次序不同也有關係。
那麼虛夠函式為什麼可以設計成虛擬函式呢?由於虛擬函式是釋放物件的時候才執行的,所以一開始也就無法確定析夠函式的。而去由於析構的過程中,是先析構子類物件,後析構父類物件。所以,需要通過虛擬函式來指引子類物件。所以,如果不設定成虛擬函式的話,解構函式是無法執行子類的解構函式的。
所以,基於以上幾點原因,建構函式是不能夠設定成虛擬函式的,而解構函式是要設定成虛擬函式的。而且這個也是面試中會經常提及的考點。