看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《Arton0306 (Ar藤)》之銘言: : 我有一個base class叫做PlayableFile class : 有兩個class public繼承他 : 分別是 : Song class : Video class : 然後我有個陣列 其元素為PlayableFile* : 這個陣列中存有Song* Video* : 我可以由PlayableFile的mItemType知道它是哪一個 : 但當我在用到Song特有的getArtistName() : 我還是要做一個轉型 : (static_cast<Song*>(myFile[n]))->getArtistName() : 但書上說當用到static_cast的時候可能就是結構不太好的時候 : 請問是否有更好的方式? 何不把 可播放的 行為視為一種介面規範? struct Playable { virtual void play() = 0; }; 連結 Song、Video 兩個類別的不是因為他們都可以被播放, 而是 因為他們都是 一種媒體: struct Media { private: std::string performer; // other members ... }; performer 在視訊中表示演員, 在音訊中則表示歌手, 儘量挖出兩 種檔案的共同處, 這才是你必須建立父類別的理由( 有子類就不需 要type code, 如你的mItemType). 類別圖: ┌───┐ │Media │ ┌────┐ └───┘ │Playable│ △ └────┘ │ △ ┌───┴───┐ │ ┌─┴─┐ ┌─┴─┐ │ Song ├┐ │Video ├ ─ ┤ └───┘ └───┘ └ ─ ─ ─ ─ ─ ┘ 使用上就有兩種情境: 1. 播放音訊/視訊: vector<Playable*> playlist; playlist.push_back( new Video ); playlist.push_back( new Song ); playlist.front()->play(); 2. 查看檔案屬性: vector<Media*> files; files.push_back( new Video ); if( Video *video = dynamic_cast<Video*>(files[0]) ) { // 針對影片特有屬性作操作 } else if( Song *song = dynamic_cast<Song*>(files[0]) ) { // 針對歌曲特有屬性作操作 } // 注意兩種轉型運算子的差別 如果轉型需求過大, 表示將他們硬是繼承同樣的父類是不合理的. 繼承通常也帶有多型行為, 如果你的父類都沒有虛擬函式可以減少 轉型的需求, 考慮改用 has-a 的架構. -- ▂▂ ▄▂ T.T.L Listen 2 http://ppt.cc/jIUk ˇ ˇˇ ˇ 說什麼結束 ▃▃ http://ppt.cc/zQtB ψ髮箍 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.121.197.115 ※ 編輯: loveme00835 來自: 140.121.197.115 (05/07 02:52)
james732:推板主 05/07 02:55
Ting1024:真是太強悍了... :D 05/07 04:31
POSIX:推! 05/07 07:02
xatier:版主強悍! 05/07 14:40
tomap41017:推版主 05/07 14:43
Arton0306:多謝板主! 05/07 17:12
angleevil:版主好強 05/09 14:26