何をしたいのための簡単な方法は次のとおりです。
enum datatype
{
dt_none,
dt_char,
dt_uchar,
dt_short,
dt_ushort,
dt_long,
dt_ulong,
dt_float,
dt_double
};
struct Any
{
datatype type; // To know what is stored inside union, not mandatory if you know that in another way
union
{
char vchar;
unsigned char vuchar;
short vshort;
unsigned short vushort;
long vlong;
unsigned long vulong;
float vfloat;
double vdouble;
} data;
};
std::vector<Any> mydata;
あなたは労働組合の使用を避けることができますが、それより多くのメモリ(各値+実際の大きさのためにポインタを)取ると、それは使用することがより複雑だ:
struct Any
{
private:
void * data;
datatype type;
public:
Any():
data(NULL),
type(dt_none)
{}
~Any()
{
deleteData();
}
void deleteData()
{
// Because deleting a void * is UB, we have to check real datatype
if (data != NULL)
{
if (type == dt_char)
delete static_cast<char *>(data);
if (type == dt_uchar)
delete static_cast<unsigned char *>(data);
....
}
}
datatype getType() const
{
return type;
}
void setChar(char v)
{
deleteData();
data = new char(v);
type = dt_char;
}
char toChar() const
{
return *static_cast<char *>(data);
}
.....
void setDouble(double v)
{
deleteData();
data = new double(v);
}
double toDouble() const
{
return *static_cast<double*>(data);
}
};
可能な最適化、いくつかのバイトを保存するために、小型のタイプのデータを格納するためのポインタを使用している(しかし、それに車を行いますefully!)。しかし、大きなタイプのデータをたくさん格納すると、さらに良いunion
が保存されます。また、ポインタのサイズはプラットフォームに依存するため、ポインタに直接格納できるタイプと移植可能なコードを選択することは困難です。また、64ビットのコンピュータでは、ポインタのサイズは8バイトであり、これも普通のサイズであるdouble
です(この場合、ポインタはすべてunion
と同じメモリ消費量ですが、本当に複雑で安全ではありません):
struct Any
{
private:
void * data;
datatype type;
public:
Any():
data(NULL),
type(dt_none)
{}
~Any()
{
deleteData();
}
void deleteData()
{
// Because deleting a void * is UB, we have to check real datatype
if (type != dt_char && type != dt_uchar && data != NULL)
{
if (type == dt_double)
delete static_cast<double *>(data);
....
}
data = NULL;
}
datatype getType() const
{
return type;
}
void setChar(char v)
{
data = reinterpret_cast<void *>(v);
}
char toChar() const
{
return static_cast<char>(reinterpret_cast<intptr_t>(data));
}
.....
void setDouble(double v)
{
deleteData();
data = new double(v);
}
double toDouble() const
{
return *static_cast<double*>(data);
}
};
あなたはあなたのケースで唯一の2つのシンプルなソリューション(私見)持っていると言ってすべてのこと:あなたが本当にメモリを節約したい場合は、
- をあなたがタイプごとにベクトルを使用する必要があります。
- または
union
PSを使用します。また、boost::any
のようなサードパーティのライブラリを見てみることができます。
タイプ消去はどうですか? –
[C++クラスラッパーの基本型の可能な複製](http://stackoverflow.com/questions/17793298/c-class-wrapper-around-fundamental-types) –
ユニオンはおそらくあなたのためのものです。 –