以乙個object的內容作為另乙個class object的初值的三種情況:
對乙個object做顯式的初始化操作; class x{};x x; x xx = x;
當object被當做引數交給某個函式 extern void foo(x x); void bar()
當函式傳回乙個class object時 x foo_bar()
如果class沒有提供乙個explicit copy constructor又當如何?當class object以「相同class的另乙個object」作為初值,其內部是以所謂的default memberwise initialization手法完成。
default memberwise initiazation: 把每乙個內建的或派生的data member(例如乙個指標或乙個陣列)的值,從某個object拷貝乙份到另乙個object身上。不過它並不會拷貝其中的member class object,而是以遞迴的方式施行memberwise initialization。
什麼時候乙個class不展現出「bitwise copy semantics」呢?(需要編譯器合成)
有4種情況:
當class內含乙個member object而後者的class宣告乙個copy constructor時(不論是被class設計者顯示地宣告,就像前面的string那樣;或是被編譯器合成,像class word那樣)。
當class繼承自乙個base class而後者存在乙個copy constructor時(再次強調,不論是被顯式宣告或是被合成而得);
當class宣告了乙個或多個virtual functions時;
當class派生自乙個繼承串鏈,其中有乙個或多個virtual base classes時。
重新設定virtual table的指標(第三種情況)
當class宣告了乙個或多個virtual functions時,編譯期間的兩個程式擴張操作:
a. 增加乙個virtual function table(vtbl),內含每乙個有作用的virtual function的位址;
b. 乙個指向virtual function table的指標(vptr),安插在每乙個class object內。
當編譯器匯入乙個vptr到class之中時,該class就不再展現bitwise semantics了。現在,編譯器需要合成出乙個copy constructor以求將vptr適當地初始化,下面是個例子:
class zooanimal ;
class bear : public zooanimal;
bear yogi; // default bear constructor初始化, yogi的vptr被設定指向bear class的virtual table (靠編譯器安插的**完成)
bear winnie = yogi; // 把yogi的vptr值拷貝給winnie的vptr是安全的
zooanimal class object以另乙個zooanimal class object作為初值,或bear class object以另乙個bear class object作為初值,都可以直接靠「bitwise copy semantics」完成(除了可能會有pointer member之外。為了簡化,這種情況被我革除)。
當乙個base class object以其derived class的object內容做初始化操作時,其vptr複製操作也必須保證安全,例如:
zooanimal franny = yogi; //這會發生切割sliced 行為
franny的vptr不可以被設定指向bear class 的virtual table(但如果yogi的vptr被直接「bitwise copy」的話,就會導致此結果),否則當下面程式片段中的draw()被呼叫而franny被傳進去時,就會「炸毀」:
處理virtual base class suboject(第四種情況)virtual base class 的存在需要特別處理。乙個class object如果以另乙個object作為初值,而後者有乙個virtual base class suboject,那麼也會使「bitwise copy semantics」失效。
每乙個編譯器對於虛擬繼承的支援承諾,都代表必須讓「derived class object 中的virtual base class suboject位置」在執行期準備妥當。維護「位置的完整性」是編譯器的責任。「bitwise copy semantics」可能會破壞這個位置,所以編譯器必須在它自己合成出來的copy constructor中做出仲裁。
C 中Copy Constructor的構造操作
class x x x 第一種 x xx x 第二種 值傳遞給函式 void test x x 第三種 作為函式返回型別 x test 當class object以相同class的另乙個object作為初值時,其內部是以default memberwise intialization 預設成員逐次初...
預設建構函式 建構函式 複製建構函式和賦值操作符
這幾個概念比較容易混淆,總結一下。預設建構函式是沒有引數 和類同名的建構函式。當乙個類沒有任何建構函式時,編譯器將會合成乙個預設建構函式。那麼編譯器合成的預設建構函式是做什麼用的呢?是初始化類的成員變數嗎?事實上不是。編譯器合成的預設建構函式只是滿足編譯器的需要,而不是按照程式設計師想的去做。更詳細...
jQuery中的DOM操做 樣式操做
利用attr 方法來實現該功能 1 獲取 var p class p attr class 獲取p元素的class 2 設定 var p class p attr class high p元素的class為high利用addclass 方法來實現該功能 p addclass another 為p元素...