推 aa155495:想知道+1 01/15 08:49
推 aecho:想知道+1 ^^ 01/15 08:58
→ adrianshum:可以呀, 沒問題 01/15 10:30
推 stonehomelaa:是可以 不過最好不要 container dtor不是virtual 01/15 12:08
→ stonehomelaa:Effective C++ 2/e item 14有詳細解說 01/15 12:09
→ yoco315:3F 片倫 XD 01/15 13:19
→ loveme00835:可以, 我覺得最好private 繼承, 類似composition 01/15 14:35
→ loveme00835:來源同5樓 01/15 14:36
→ adrianshum:@yoco315: 我哪裡騙人了? 明明就可以呀 01/15 15:28
→ adrianshum:有沒有 virtual dtor 這些, 無論你在 inherit 任何 stl 01/15 15:29
→ adrianshum:或非 stl 的 class 也要留意的, 和這問題沒有關係吧 01/15 15:29
→ adrianshum:另 private 繼承也不合原問,因為他是想增加某method. 01/15 15:30
→ adrianshum:用 private inheritence, 本身 vector 提供的東西就完 01/15 15:31
→ adrianshum:全不 visible to outside 了 01/15 15:31
→ tinlans:答案是 private 繼承 + 重新 wrap 一次 base 的 methods。 01/15 15:37
→ tinlans:先用這種方法做出帶 virtual function 的可繼承基底,以後 01/15 15:39
→ adrianshum:樓上所說的不是不可以, 但不太算是新增 method 了 01/15 15:40
→ tinlans:想再繼承就很方便,但 ctor 這類東西繼承了還是得重包一次 01/15 15:40
→ adrianshum:因為新的 class 不再 is-a vector 01/15 15:40
→ tinlans:怎麼不算是新增 method?只是多做一點準備的工而已。 01/15 15:41
→ tinlans:本來就不能有 is-a 關係,is-a 必須實現多型語意, 01/15 15:41
→ tinlans:programmer 可以寫 vector<int> *v = new MyVector; 01/15 15:42
→ tinlans:然後 delete v; 01/15 15:42
→ tinlans:然後就.....是沒有 virtual dtor 可能發生的問題會發生。 01/15 15:43
→ adrianshum:為什麼 "本來就不能有 is-a" ? public inheritence 就 01/15 15:43
→ tinlans:所以應該是使用 STL 容器的 class 實作一個可以延伸的基底 01/15 15:44
→ tinlans:類別,也就是 is-implement-in-terms-of,再繼承這種類別 01/15 15:44
→ tinlans:才可以有 is-a 關係。 01/15 15:44
→ adrianshum:是了啦? 01/15 15:44
→ tinlans:public 繼承是 is-a 的必要條件,但不是充分條件。 01/15 15:46
→ adrianshum:只是要留心有哪些東西沒 virtual, 但加 method 這類程 01/15 15:47
→ tinlans:在 Java 的話,因為預設 dynamic binding,所以才等價。 01/15 15:47
→ adrianshum:度, 用 public inheritence 沒有什麼問題吧 01/15 15:47
→ adrianshum:你說的這個 point, 與是不是 stl 沒直接關係.一向在C++ 01/15 15:48
→ adrianshum:要 inherit 別的 class, 都要留心 virtual 與否. 這會 01/15 15:48
→ tinlans:is-a 是一種 OO 概念,C++ 要充分支援它並不能單靠 public 01/15 15:49
→ adrianshum:影響 method overriding 的結果, 但並不令 is-a 關係不 01/15 15:49
→ tinlans:繼承,這也是為什麼 N 年前 Effective C++ "2/e" 就已經 01/15 15:49
→ tinlans:列出了 Item35: Make sure public inheritance models 01/15 15:50
→ adrianshum:存在. 只是 "雖然MyVector is-a vector, 但由於 vector 01/15 15:50
→ tinlans:"isa." 01/15 15:50
→ adrianshum:的某某 method 非 virtual, 所以不適合 override" 而已 01/15 15:50
→ james732:我好想建議兩位回文章來討論...XDDD 01/15 15:51
→ adrianshum:我也覺得好亂 :P 01/15 15:51
→ tinlans:問題不是出在適不適合 override,而是 dervied class 必須 01/15 15:52
→ tinlans:override base 的 dtor,但無法這麼做,使 is-a 語意不全 01/15 15:52
→ adrianshum:要是自己本身根本沒有 extra dtor logic 的話, 根本不 01/15 16:04
→ adrianshum:需要 override dtor 也沒問題呀, 這就和 override non- 01/15 16:05
→ adrianshum:virtual method 的情況類似罷了 01/15 16:05
→ adrianshum:is-a 語意並不會因為不能 override dtor 而不全... 01/15 16:06
→ adrianshum:只是當有 custom dtor logic 的話, 就要知道因為 base 01/15 16:07
→ adrianshum:class dtor 非 virtual, 這情況我不能直接 override 了 01/15 16:07
→ tinlans:delete v 的語意應該是,我要摧毀任何 is-a vector<int> 01/15 16:13
→ tinlans:的類別實體,但是實際上的語意卻是只摧毀了屬於 01/15 16:14
→ tinlans:vector<int> 所屬的那個部分,即使你沒在 MyVector 裡加入 01/15 16:14
→ tinlans:任何 data members 或 allocate 任何資源,語意上卻還是完 01/15 16:15
→ tinlans:全不一樣的,實際上大部分的書也會告訴你 C++ std 對這行 01/15 16:15
→ tinlans:為未有定義,因為 C++ compiler 可以把任何程式碼偷偷安插 01/15 16:16
→ tinlans:在 dervied class 的 dtor,沒呼叫到就不會跑到。 01/15 16:16
→ tinlans:在你的編譯環境 compiler 不會插任何東西,只能代表這個 01/15 16:17
→ tinlans:做法在你的編譯環境可行;但無論如何它實施的行為確實是 01/15 16:17
→ tinlans:只摧毀到 base 所屬的那一部份,derived 的 dtor (不管是 01/15 16:18
→ tinlans:你手寫的還是 compiler 幫你產生的) 都從未被呼叫到。 01/15 16:18
→ tinlans:換句話說,delete v 的行為並未做了 C++ 解構物件應該做的 01/15 16:19
→ tinlans:事情,因為它沒有真正把整個物件解構,而是一部分。 01/15 16:19
→ tinlans:因此從抽象面說,就是:programmer 期望摧毀整個物件,但 01/15 16:22
→ tinlans:實際上卻是只有摧毀物件的一部份,即使它的行為正確,也沒 01/15 16:22
→ tinlans:有對程式的執行環境造成任何損害。 01/15 16:22
→ tinlans:實作面來說,就是 compiler 產生在 dervied class 裡的 01/15 16:24
→ tinlans:dtor 本來應該在摧毀整個物件時被呼叫到,但它沒有被呼叫 01/15 16:24
→ tinlans:而所謂「compiler 可以在 dtor」裡插入任何東西是一件很重 01/15 16:30
→ tinlans:要的事情,因為比較先進的 compiler 可能允許 user 下參數 01/15 16:31
→ tinlans:後內插一些分析程式的 code,用來統計或分析程式的行為, 01/15 16:32
→ tinlans:如 profiling / power consumption / thread anlaysis / 01/15 16:32
→ tinlans:memory leak detection 等等,以最後那個為例,可能就會 01/15 16:33
→ tinlans:讓程式執行下去後回報有 memory leak XD 01/15 16:33
→ adrianshum:的確我沒有考慮到 compiler 自動安插的 dtor logic :) 01/15 16:52
→ adrianshum:如果考慮這個在內的話的確不適合直接 inherit 了. 01/15 16:53
→ adrianshum:多謝指教 :D 01/15 16:53
→ adrianshum:不過, 如果肯定不會 delete thru vector* , 這也不是問 01/15 17:03
→ adrianshum:題吧. 最重要是知道這樣做的後果 01/15 17:03
→ johnhmj:即使這個繼承方式可以被編譯成功、執行無誤… 01/15 17:29
→ johnhmj:而它仍然不是一種適當的繼承方式,對吧? 01/15 17:36
推 dendrobium:大家應該用回文的@@a 01/15 17:59
→ johnhmj:感謝大大們的解答! 01/15 20:27
→ sunneo:精彩 01/15 22:56