使用向量在结构中输入值

时间:2012-10-19 06:01:39

标签: c++

我创建了这个结构:

struct xlsmain {
    vector<sub_parts> sb;
    string name;        
}

struct sub_parts {
    vector<pio_parts> pio;
    string name_pio;
    string direction;
    string partition;
}

struct pio_parts {
    string pio_name;
    vector<report_specs> report;
}

struct report_specs {
    string name; 
    vector<string> value;
}

struct xlsmain* interface = new xlsmain[100];

嵌套是必要的,因为每个元素都以层次方式相关。我现在面临的问题是如何在这个结构中输入值。

编辑:我不喜欢使用push_back(),因为每次我都必须声明一个单独的结构。因此,例如,如果我想向xlsmain添加子部分,我必须声明一个变量:

sub_parts sb1;

然后我必须将值输入到此结构中,直到它完成,然后我可以使用:

interface[i].sb.push_back(sb1);

此外,如果涉及嵌套,则还必须创建许多结构,如sb1。这导致必须创建大量变量才能在我的结构中输入单个值。

2 个答案:

答案 0 :(得分:0)

在编辑之前,您对push_back()“过于复杂”的担忧并不明确。 (听起来好像甚至你不喜欢这个方法的名字......还是那种奇怪的东西?)

我会尝试解决提出的新问题。但我要重申,尽管您使用的是标准库stringvector类,但您的结构本身并不具备C ++的优势!

您没有构造函数,析构函数或方法。这些是让数据对象“活跃起来”的基础,具有“魔术”行为,使这些类的客户端能够编写更简单,更抽象的代码。即使您唯一的“客户”只是您自己的代码,这也很有用!

在你有代码之前说:

pio_parts pp;
pp.pio_name = "this string will be stored in the name";
pp.report.push_back(someReport);
pp.report.push_back(anotherReport);

如果在结构中添加构造函数和方法,请执行以下操作:

struct pio_parts {
    string pio_name;
    vector<report_specs> report;

    pio_parts(string newName) {
         pio_name = newName;
    }

    void addReport(report_specs newSpecs) {
         report.push_back(newSpecs);
    }
};

然后上面的代码变得更好了:

pio_parts pp ("this string will be stored in the name");
pp.addReport(someReport);
pp.addReport(anotherReport);

尽管如此,除了必须知道pio_parts中要添加的数据成员的名称之外,您还没有做多少工作。现在你记得一个方法名称。你节省了一点点打字,但push_back()差不多。

如果您需要在addReport()内进行更多相关操作,而不仅仅是添加到向量,那么您现在可以放置所有代码。这样,您班级的用户就不必担心添加报告所需的任何记账......他们只是要求它完成!此外,由于没有对push_back()的调用,因此不再需要任何正在调用addReport()的人知道该列表存储在向量中。

我故意甚至不打算尝试深入研究引用,复制构造,智能指针,成员初始化语法甚至class vs struct的具体细节。这语言太深了。尽快抽出时间,仔细阅读这篇由Bjarne Stroustrup撰写的简短文章,其中阐述了方法论中明显的对比:

Learning Standard C++ as a New Language


现在我会尝试继续你的另一个问题。首先,您不必在C ++中创建变量的命名实例以将其传递给函数。你可以改写:

sub_parts sb1;
interface[i].sb.push_back(sb1);

......相反:

interface[i].sb.push_back(sub_parts ());

在这种情况下不是特别有用,因为对象被构造为空...所以你只是把东西推得无用。但是如果你的构造函数接受了填充对象的参数,那就没问题了。您甚至可以构建这样的数组:

How can I initialize an array of objects whose constructor require two or more arguments?

但是如果你的构造函数采用了一个硬编码列表(就像你看来的那样),那么美中不足的就是它。虽然C ++可以使用您直接编码的值初始化普通数组,但传递普通数组会丢失其长度信息。向量会更好,但用硬编码值初始化它们是笨重的:

What is the easiest way to initialize a std::vector with hardcoded elements?

你可以看到人们对你必须写的抱怨几乎一样:

std::vector<int> ints;

ints.push_back(10);
ints.push_back(20);
ints.push_back(30);

该帖子列出了一些变通方法,但是前沿的编译器(可能不是你正在使用的)支持:

std::vector<int> ints = {10, 20, 30};

一旦拥有了这些,就可以非常轻松地进行“嵌套”式的构造。


作为最后一点:您似乎在earlier comment上具体询问原始数组与向量。对于你的interface,你几乎肯定想要一个向量。这是一个陷阱:在原始数组上使用new xlsmain[100]需要记住执行delete[] interface(而不仅仅是常规delete interface):

delete vs delete[] operators in C++

请记住,无论如何也有no realloc in C++。因此,如果这就是您动态分配它的原因,那就忘记这个想法了。

只需将界面设为矢量,就可以避免这样的麻烦。如果您需要,您可以调整它的大小,并避免将所谓的"Magic Number"硬编码到您的程序中。

答案 1 :(得分:0)

一个选项是使用std :: map而不是vector,然后你可以做这样的事情

xmlsmain["some element"].sb["some other"].direction = "up";

通过这种方式,会自动创建元素“some element”和“some other”。