在建構函式內呼叫non final函式時要當心

2021-06-27 02:51:29 字數 1059 閱讀 1335

當程式新建乙個class物件時,class建構函式會被呼叫。建構函式的目的在於將物件初始化。建構函式在執行期間可以呼叫class的某些函式,這很普遍,因為那些被呼叫的函式或許包含一些初始化動作。舉個例子:

class base

public int lookup()

public int value()

}class base的構造函式呼叫了乙個non-final函式lookup(),查詢資料庫中的一些資料。這段**的運轉與設想相同,base的instance資料val被賦值為5.

想像一下,如果乙個derived class覆寫了base的lookup()會怎麼樣?這種做法可能導致不易察覺的結果。例如:

class base

public int lookup()

public int value()

}class derived extends base

}class test

}**輸出如下:

from main() d.value() returns 0

問題出在derived的lookup()返回值居然是0。你可能奇怪這是怎麼發生的,明明已經有了函式實現**呀!該函式返回instance變數num,它在instance變數初始化時被賦值為10。事實真相是,當derived的lookup()開始執行時,其instance變數初始化工作還未來得及進行呢。

注意,這個lookup()是在derived物件建構期間由base構造函式呼叫的,而base建構函式是被derived建構函式自動呼叫的。當執行權進入deived的lookup()時,其instance變數初始化行為尚未進行。這種情況下,那些instance變數僅僅被設定為預設初值(default initial values)。因此當時的val被設定為0,於是0被傳出去(praxis32非常細緻地分析了物件的建構和初始化步驟)。

當構造函式呼叫non-final函式時,就有可能發生這種錯誤。如果該函式被乙個derived class覆寫,而且該函式返回乙個在「instance變數初始化期間」被初始化的值,就會產生問題。這種錯誤或許不太常見。不過知道它的存在還是好的,萬一哪天遇上了,就可以節省大量時間。

C 解惑 1 在建構函式內呼叫虛方法

在c 中,用virtual關鍵字修飾的方法 屬性 事件 稱為虛方法 屬性 事件 表示該方法可以由派生類重寫 override 虛方法是.net中的重要概念,可以說在某種程度上,虛方法使得多型成為可能。然而虛方法的使用卻存在著很大學問,如果濫用的話勢必對程式產生很大的負面影響。比如下面這個例子 pub...

C 基礎 在建構函式內部呼叫建構函式

看下面的面試題 include using namespace std struct cls cls int main 列印的結果是系統的乙個隨機值。所以這種直接在建構函式中呼叫另外的乙個建構函式是不可行的。奇怪的地方在於建構函式中呼叫了自己的另乙個建構函式 我們知道,當定義乙個物件時,會按順序做2...

構造函式呼叫建構函式

題目如下 問下列 的列印結果為0嗎?include stdlib.h include iostream using namespace std struct clscls int main 列印結果是不定的,不一定為0 奇怪的地方在於建構函式中呼叫了自己的另乙個建構函式 我們知道,當定義乙個物件時,...