看板 C_and_CPP 關於我們 聯絡資訊
最近缺錢, 發文賺一下p幣這樣 ※ 引述《whoowh (AA)》之銘言: : class Set : { : protected: : Base* dataArray; : public: : run1() : { : int c = 5; : dataArray = new derived[c]; : cout << dataArray[3].getA(); // case 1 透過 operator[] 取得第 4 個元素並呼叫其 method : } : }; : run2(Base* b, int index ) : { : cout << b[index].getA(); 一樣是透過 operator[] 來取值 : } 推文所講的問題我就不再贅述, 來介紹不改變相依性的解法, 因為你把 run1() 的定義寫在 Set 型別規範內, run1() 裡面 又有 new Derived[c] 這敘述, 所以多加一行 cast 也不為過 1 int c = 5; 2 dataArray = new Derived[c]; 3 Derived * derived_array = static_cast<Derived*>(dataArray); 4 cout << derived_array[3].getA(); 你可以發現這時候程式碼對 dataArray 的需求就只是要把任何 子類別物件接起來而已, 所以它的型態可以為 void* class Set { protected: void* dataArray; // ... }; 再來我們可以把 line (2) 的程式碼用專責函式包起來 template <typename T> void Set::allocate( size_t n ) { dataArray = new T[ n ]; } 加上用來存取元素的函式 template <typename T> T& Set::at( size_t idx ) { return static_cast<T*>(dataArray)[ idx ]; } 最後你的 run1 就變成這樣了 void run1() { int c = 5; allocate<Derived>( c ); cout << at<Derived>( 3 ).getA() << endl; } run2 轉成模板就變成這樣 template <typename T> void run2(T * b, size_t index ) { cout << b[index].getA(); } main() 的實作都不用改, 當然不想要因為 run2 改成這樣彈性 太大的話, 可以查查 'SFINAE' -- ╔═══╗╔═══╗ ╔═╗═╗╔═══╗╔═══╗╔╦═╦╗ 金栽經║ ╔╗ ║║ ╔╗ ║╔╗║ ║ ║║ ═ ║║ ╔╗ ║║║ ║║RAINNOUS ≡≡║ ╚╝ ║║ ╚╝ ║║║║ ║║ ╞╣║ ║║ ║║ ║ ═╣║ ╥ ║║║║ ║ ║║ ═ ║║ ╚╝ ║║ ║ ║ 高佑麗╚═╩═╝╚═╩═╝╚╝╚═╚═╝╚═══╝╚═══╝╚═╩═╝鄭允慧 趙賢榮金智淑盧 乙吳勝雅ψmocki -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.121.197.115
james732:未看先推 06/07 17:05