具有未知数据类型的C ++结构 [英] C++ Structure with unknown data types
问题描述
用户输入:
创建表
添加属性字符串名称
添加属性int年龄
行3
我需要从用户的输入准备一个结构。我有这样的东西:
CTable
{
unsigned attributesCnt;
string * attributesNames;
void **属性;
};
所以,从用户的输入,程序执行这些步骤:
CTable myTable;
myTable.attributesCnt = 2; // stringName,intAge
myTable.attributesNames = new string [2];
myTable.attributesNames [0] =名称;
myTable.attributesNames [1] =年龄;
属性= new void [2]; // 2属性
attributes [0] =(void *)new string [3]; //会有3行
属性[1] =(void *)new int [3];我需要记住,attributes [0]是字符串,attributes [1]是int
这是正确的方式吗?
我只想使用标准库。 >
解决方案你正在寻找的是一个标记的联盟,也称为变体。它允许您在同一位置存储多个数据类型,就像常规联合,但包括一个附加但单独的数据成员,表示它的类型。 C ++标准库不包括变体,但它们很容易实现。
一旦你有一个变体,你可以将它应用到你的例子如下。
myTable.attributesNames [0] =名称;
myTable.attributesNames [1] =年龄;
//我建议在这里使用std :: vector,而不是使用new / delete自己
attributes = new Variant * [2]; // 2 attributes
attributes [0] = new Variant(player name);
attributes [1] = new Variant(player_age);
以下示例显示了该变体可能如何实现。
struct Variant
{
枚举类型
{
INT,
STRINGPTR
};
类型type_;
union
{
int int_;
const char * stringptr_;
} data_;
显式变量(int data):type_(INT)
{
data_.int_ = data;
}
显式变量(const char * data):type_(STRINGPTR)
{
data_.stringptr_ = data;
}
输入getType()const {return type_;
int getIntValue()const
{
if(type_!= INT)
throw std :: runtime_error(Variant is not an int);
return data_.int_;
}
const char * getStringPtr()const
{
if(type_!= STRINGPTR)
throw std :: runtime_error(Variane not not一个字符串);
return data_.stringptr_;
}
};
int main()
{
Variant intval(1);
Variant stringval(hello);
std :: cout<<< intval.getIntValue()<< std :: endl;
std :: cout<<< stringval.getStringPtr()<< std :: endl;
}
My program reads user's input and create easy "table". User on the start specifies data types of columns and the number of rows.
User's input:
create table
add attribute string Name
add attribute int Age
rows 3
I need prepare a structure from user's input now. I have something like this:
CTable
{
unsigned attributesCnt;
string * attributesNames;
void ** attributes;
};
So, from the user's input, the progam does these steps:
CTable myTable;
myTable.attributesCnt = 2; // string "Name", int "Age"
myTable.attributesNames = new string[2];
myTable.attributesNames[0] = "Name";
myTable.attributesNames[1] = "Age";
attributes = new void[2]; // 2 attributes
attributes[0] = (void*) new string[3]; // there will be 3 rows
attributes[1] = (void*) new int[3];
I need remember that "attributes[0]" is string and "attributes[1]" is int too.
Is this "right" way?
I would like use only standard libraries.
解决方案 What you are looking for is a tagged union also called a variant. It allows you to store multiple data types at the same location just like a regular union but includes an additional but separate data member that indicates it's type. The C++ Standard Library does not include variants but they are easy enough to implement.
Once you have a variant you can apply it to your example like below.
myTable.attributesNames[0] = "Name";
myTable.attributesNames[1] = "Age";
// I recommend using std::vector here instead of using new/delete yourself
attributes = new Variant*[2]; // 2 attributes
attributes[0] = new Variant("player name");
attributes[1] = new Variant(player_age);
The following example shows how the variant might be implemented.
struct Variant
{
enum Type
{
INT,
STRINGPTR
};
Type type_;
union
{
int int_;
const char* stringptr_;
} data_;
explicit Variant(int data) : type_(INT)
{
data_.int_ = data;
}
explicit Variant(const char *data) : type_(STRINGPTR)
{
data_.stringptr_ = data;
}
Type getType() const { return type_; }
int getIntValue() const
{
if(type_ != INT)
throw std::runtime_error("Variant is not an int");
return data_.int_;
}
const char *getStringPtr() const
{
if(type_ != STRINGPTR)
throw std::runtime_error("Variane is not a string");
return data_.stringptr_;
}
};
int main()
{
Variant intval(1);
Variant stringval("hello");
std::cout << intval.getIntValue() << std::endl;
std::cout << stringval.getStringPtr() << std::endl;
}
这篇关于具有未知数据类型的C ++结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!