Re: [討論] 面試有鑑別度的問題??

看板C_and_CPP作者 (AzureBlaze)時間11年前 (2013/01/08 11:41), 編輯推噓2(207)
留言9則, 2人參與, 最新討論串6/14 (看更多)
※ 引述《legnaleurc (CA)》之銘言: : : 推 xvid:這篇有好心人願意解答嗎? 01/08 00:5 : 我是斗M,快來鞭我 ._./ 一些想法請鞭 : ※ 引述《littleshan (我要加入劍道社!)》之銘言: : : 標題: Re: [討論] 有鑑別度的問題?? : : 時間: Mon Jan 7 00:13:59 2013 : : 隨便想的幾個題目 : : 1. 若在 class 中定義了 destructor,則通常還需要定義另外兩個 function。 : : 為什麼? : copy assignment operator 和 copy constructor : 如果有需要自訂解構行為通常也會影響到 copy 語意 : 不過因為 C++ 夭壽複雜的規則,有時也會有例外 需要non-virtual dtor通常代表你的class有new東西要delete 也就是說需要手動資源管理。這時候compiler幫你=每個member的 shallow copy就不合用了,所以每個跟copy有關的東西都要重寫 因此copy ctor應該要複製這些物件,而不是指標而已 assignment operator必須要把本來的物件delete掉再複製新的 這兩個東西就算你沒有a=b,函數pass by value或是return by value 的時候還是會偷偷用到,所以不定義很容易出問題 不過個人嫌他們麻煩,所以函數通常都直接操作pointer或reference 真的需要的時候再另外提供clone的函數 這兩個就只宣告成private而不定義內容。 讓不小心用到的時候complier或linker把他擋下來 : : 2. mutable 這個關鍵字應該用在什麼地方? : 被 mutable 修飾的成員即使在 const method 裡也可以被修改 : 這跟 volitale 一樣是不太常用的 cv 修飾字 : 用途嘛 ... 有時候你會需要在 const method 重用 non-const 版本 : 不過我個人是會避開就是了 mutable我覺得主要的用意是分別概念上的const和程式碼上的const 像是 class String{ char data[SOME_FIXED_SIZE]; int length() const; }; 你希望length()只有被用到的時候才實際計算長度, 可是又不希望每次length()都要重新呼叫strlen因為data根本就沒變 length()應該是const因為他不會改到data的內容 這時候就可以另外宣告一個 class Sting{ ... mutable int m_length = -1; }; int String::length() cosnt{ if(m_lenght < 0){ m_lenght = strlen(data); } return m_length; } 這樣就可以這些其實概念上不影響資料的support funciton就可以更有彈性和效率 另外我覺得如果需要const_cast,那就應該直接把cosnt拔掉 除非要亂搞別人的library而且你很清楚你在幹麻 : : 3. 為什麼 C++ 有四種不同的 cast operator? 因為C-style cast包含了以下四種功能而且是哪種有時候不是很明確 : static_cast: 顯式轉型(e.g.: 大轉小,有號無號 ... etc.) 對物件用的時候會呼叫cast operator 轉換不一樣但是有定義之間轉換關係的物件 例如static_cast<int>(1.5f); // => 1 class A{ int x; operator int() const{ return x * 100; } }; A a; a.x = 123; static_cast<int>(a) // => 12300 如果沒有定義轉換就會error 用在pointer上的時候會在compile time判斷這個轉換是否有可能成功 class A; class B:A; class C:A; class D; A *a; B *b; C *c; D *d; static_cast<A*>(b) //OK b一定是一個A static_cast<B*>(a) //OK a有可能是一個B static_cast<C*>(b) //error b不可能是C static_cast<A*>(d) //error A D根本沒關係 : const_cast: 去掉 CV 修飾字 : dynamic_cast: 向下轉型,失敗會是 nullptr 跟上面static_cast pointer的一樣 只是 dynamic_cast<B*>(a) 會在runtime判斷a 到底是不是一個 B 另外dynamic_cast需要開RTTI才有runtime檢查的功能 可是有人不喜歡RTTI, 覺得他沒效率 或是覺得你compile time就該清楚a是不是B,不然就用virtual method : reinterpret_cast: 以上三種以外的情況用這種,但後果要看 compiler 管他有沒有關係硬轉 不會對資料內容動手腳,只拔掉型態檢查 常用在把void *轉回你要的東西 reinterpret_cast<MyClass*>(userData); 或是把float當成int來取hash之類的 hash += *reinterpret_cast<int*>(&f); : 不是不好,很多時候只能這麼轉,像是 function pointer : 不同場合用不同的 cast,用 grep 比較好找(?) : : 4. exception 有什麼優點和缺點? : 戰文。 我討厭exception 戰! : : 5. C++ 提供多重繼承,但 C# 或 Java 都採用 interface 與單一繼承。 : : 允許多重繼承有什麼缺點? : 最明顯的問題是可能會出現鑽石狀繼承圖 class B; class D1 : B; class D2 : B; class D : D1,D2; 這時候你的D裡頭其實有兩個不同的B: D1::B 和D2::B 用B的時後會搞不清楚在用哪一個 : Java 所有物件都繼承自 Object,要是能多重繼承,鑽石就來了 : C++ 讓使用者自已解決 : 好處是設計自由,衍生出如 policy-based design 等手法 : 但壞處是你要處處小心不要炸了自已的腳,還要記得用 virtual inheritance : 另外 C++ 很鳥的地方是多重繼承後的指標,在大部分的 compiler 上會有 offset : 比方說 class C: public A, public B {}; : C * c = new C; : A * a = c; : B * b = c; : 指標的值,b 會和 c 不一樣,但是 b == c 是 true : 這代表什麼,代表存在陣列裡的多型指標都不可信 : 因為陣列需要計算指標的 offset : : 6. 為什麼我們要避免使用 global variable? : : Singleton 是 global variable 嗎?為什麼? : 一個非 const 變數存在的 context 越大,它就越難掌控 : 你很難一眼看出來哪些程式碼依賴這個變數 : 還有最重要的 multithreading 同步問題 : 關於 Singleton,還是戰文 : 我的看法是,這東西就是包裝精美的全域變數 : 全域變數有的缺點它全都有,只不過它讓你有方法補救 : 在 C++ 它的重點有二: : 1. 正確解構順序 : 一般來說沒什麼難的,但如果你有用到 dll ... : 2. 在 multithread 環境正確初始化 : C++ 的 memory model 其實沒考慮到 thread : 所以如果在進入 multithread 之後才想要初始化 : 那祝你好運 :) 另外Singleton有一個問題就是他同時做了兩件事: 1.到處都可以存取他 2.只能有一個 撇除「一個class只負責一件事」這個觀念不談 大部分的人用singleton的時候其實只要(1) 可是他還送你(2) 所以當你發現這個"Single"ton你其實需要很多個的時候 改那堆既有程式你就挫屎惹 : 好好的一個人,何苦學 C++? 好好一個人,何苦寫程式 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 1.171.54.154 ※ 編輯: azureblaze 來自: 1.171.54.154 (01/08 11:46)

01/08 17:01, , 1F
推詳細, 另 Singleton 也有替代方案如 Context pattern
01/08 17:01, 1F

01/09 12:55, , 2F
Singleton有一個比較不明顯的好處,就是當這個Singleton
01/09 12:55, 2F

01/09 12:55, , 3F
某天被發現其實不能只是single, 把他的管理界面從原來
01/09 12:55, 3F

01/09 12:55, , 4F
的class抽離出來是很方便簡單的。
01/09 12:55, 4F

01/09 12:56, , 5F
比方說SingleDataCluster就可以簡單的出離出
01/09 12:56, 5F

01/09 12:56, , 6F
DataClusterManagerInterface 來管理一堆DataCluster
01/09 12:56, 6F

01/09 12:57, , 7F
不過個人仍然是一看到singleton就倒彈就是....
01/09 12:57, 7F

01/09 12:57, , 8F
另外Android的java SystemManager也是用了一堆變化過
01/09 12:57, 8F

01/09 12:58, , 9F
的Singleton 像是SystemManager.getService(TELEPHONY)
01/09 12:58, 9F
文章代碼(AID): #1GwvLoZU (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1GwvLoZU (C_and_CPP)