具有未知数据类型的C ++结构 [英] C++ Structure with unknown data types

查看:239
本文介绍了具有未知数据类型的C ++结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的程序读取用户的输入并创建简单的表。用户开始指定列的数据类型和行数。



用户输入:

 创建表
添加属性字符串名称
添加属性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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆