2017-01-02 20 views
1

我有以下情形:Access數據與它的正確類型轉換派生模板類

class ScalarField 
{ 
    void* _buffer; //Array for data. 
}; 

而派生類:

template <typename T> 
class ScalarFieldT : public ScalarField 
{ 
    ScalarFieldT(int size) 
    { 
     _data = new T[size]; 
     _buffer = _data; 
    } 

    T& get(int index) 
    { 
     return _data[index]; 
    } 

    T* _data; // Typed array for data 
}; 

注意T只能假設爲基本類型如float,int,double等等。

這是一個非常古老的遺留代碼,所以我沒有太大的靈活性來適當地調整它,做出更好的設計。需要做的是從ScalarField::_buffer獲取正確類型化派生類的數據。

像這樣:

void main() 
{ 
    int n = TOTAL_SIZE; 
    ScalarFieldT<int> typedScalarField(n); 

    ScalarField* scalarField = &typedScalarField; 

    // This is what I need to do: 
    int index = ELEMENT_INDEX;   
    float value = scalarField->method(index); // Get the value from base class correctly converted from int to float, for example.  
} 

的一點是,我只能訪問的基類的抽象,但是我需要從_buffer轉換爲另一種簡單的數據類型,例如浮動,INT的值, uchar等

你們推薦什麼?

在此先感謝!

+0

你想要的'int'被鑄成一個'float'在'主()'例子,或者你打算要保證100%是' float value = scalarField-> get(index);'只會用實例化爲'ScalarFieldT'的scalarField來調用? – Frank

+0

使用'static_cast'。 –

+0

在你手頭有'ScalarField *'的地方,你知道'_buffer'指向的元素的實際類型嗎?換句話說,你知道'ScalarFieldT '這個特殊的實例是基類子對象嗎?沒有這個,恐怕你很幸運。單看'ScalarField',你就無法判斷'_buffer'是指向一個「int」數組還是「float」數組 - 但是當然數組中的實際位必須是對這兩種情況的解釋非常不同。 –

回答

0

嗯 - 請不要扔我石頭的可能愚蠢的答案,但是...

讓我們假設T僅限於數字數據類型,例如int,long,double,float,並且我們進一步假設要存儲的最大積分值大約爲2^53。然後double可以作爲數據交換數據類型,任何其他數據類型可以被轉換而不會失去精度。

然後,人們可以定義virtual double ScalarField::method(int index) = 0,然後在類型變體中相應地重載,這些類型變體從實際類型T進行「向上」播放以翻倍。

除非你被允許封裝在一個對象中的值(例如struture /類值),使用「使用雙數據交換數據類型」可以工作,下面的代碼:

class ScalarField 
{ 
public: 
    void* _buffer; //Array for data. 
    virtual double method(int index) = 0; 
}; 

template <typename T> 
class ScalarFieldT : public ScalarField 
{ 
public: 
    ScalarFieldT(int size) 
    { 
     _data = new T[size]; 
     _buffer = _data; 
    } 

    virtual double method(int index) { return get(index); } 

    T& get(int index) 
    { 
     return _data[index]; 
    } 

    T* _data; // Typed array for data 
}; 
1

您可以使用一種爲method提供一組演員操作符作爲返回類型的類型。
它遵循最小,工作示例:

#include<memory> 

class ScalarField { 
protected: 
    struct Value { 
     virtual operator float() const = 0; 
     virtual operator int() const = 0; 
     // ... 
    }; 

public: 
    virtual const Value & method(int i) = 0; 

protected: 
    void* buffer; 
}; 

template <typename T> 
class ScalarFieldT : public ScalarField { 
    struct TValue: Value { 
     TValue(T value): value{value} {} 
     operator float() const override { return float(value); } 
     operator int() const override { return int(value); } 
     // ... 

    private: 
     T value; 
    }; 

public: 
    ScalarFieldT(int size) { 
     data = new T[size]; 
     buffer = data; 
    } 

    T& get(int index) { 
     return data[index]; 
    } 

    const Value & method(int i) { 
    std::make_unique<TValue>(data[i]); 
} 

private: 
    std::unique_ptr<Value> value; 
    T* data; 
}; 

int main() { 
    ScalarFieldT<int> typedScalarField(10); 
    ScalarField* scalarField = &typedScalarField; 
    float f = scalarField->method(2); 
    int i = scalarField->method(5); 
}