推 james732:未看先推 06/07 17:05
最近缺錢, 發文賺一下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
≡≡≡≡║ ╚╝ ║║ ╚╝ ║║║║ ║║ ╞╣║ ║║ ║║ ║≡≡≡≡
≡≡≡≡║ ═╣║ ╥ ║║║║ ║ ║║ ═ ║║ ╚╝ ║║ ║ ║≡≡≡≡
≡高佑麗╚═╩═╝╚═╩═╝╚╝╚═╚═╝╚═══╝╚═══╝╚═╩═╝鄭允慧≡
≡≡≡≡≡趙賢榮≡≡≡金智淑≡≡≡RAINBOW≡≡≡盧 乙≡≡≡吳勝雅≡ψmocki
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.121.197.115