例えば、私はクラスとして、ある種のデータ型(__type)の非常に大きな配列をポインタとして格納しているとしましょう。しかし、このクラスのオブジェクトを別の型で初期化したいと思います。私が持っているコードは、以下に凝縮することができます。C++のポインタポインタのキャスト
template <typename __type> class MyStorageClass {
private:
__type* _data;
public:
template <typename __alt> MyStorageClass(int size, __alt* data) { // some init function }
extern friend print() const; // print to the screen
}
私はMyStorageClass<int>
のオブジェクトを作成し、(new int[2] { 1, 2 })
にそれを初期化する場合、これは正常に動作します。しかし、int
とfloat
のサイズは同じです(理論的には、それらはお互いにキャストされます)、(new float[2] { 1, 2 })
のように初期化しようとすると問題が発生します。
_data = (__type*) data;
で初期化すると、要素が変更されます。MyStorageClass<int> msc1(2, new float[2] { 1, 2 }); msc1.print();
収量:
msc1=[1065353216, 1073741824]
、ないmsc1=[1, 2]
私はforループを通してそれを初期化する場合:
// some init function _data = new __type[size]; for (int i = 0; i < size; i++) _data[i] = data[i];
これは動作し、適切にオブジェクトを定義します。ただし、
&data
に既に割り当てられているメモリを使用するのではなく、メモリサイズがsizeof(data)
である新しいアレイをメモリに作成します(&_data
)。これは不必要にメモリを消費し、ユーザーにとって混乱を招く可能性があります。
QUESTION:(int*
へfloat*
から、または別のデータ型)配列と同じメモリアドレスを使用してキャストする方法はありますか?
更新:ユニオンで失敗しました。
union FloatIntUnion{
float _f;
int _i;
FloatIntUnion(int i) { _i = i; }
FloatIntUnion(float f) { _f = f; }
operator float() { return _f; }
operator int() { return _i; }
operator std::string() const { std::stringstream oss; oss << _f; return oss.str(); }
};
MyStorageClass<int> msc2(2, new FloatIntUnion[2]{ float(1), float(2) });
msc2.print();
収量:msc1=[1065353216, 1073741824]
これはできません。 – Oliv
二重アンダースコア「__」を含む識別子は予約されています。 – VTT
キャストしていたすべてがfloatだった場合、その値は整数値に変換されます。この方法でポインタをキャストすると、エイリアシング規則に違反するため、技術的に何かが起こる可能性があります。おそらく、intは浮動小数点の根本的に異なる格納形式をとり、何も変換なしでそれをintoとして使用しようとします。 – user4581301