使用矢量在结构中输入值

enter values in structure using vectors

本文关键字:输入 结构      更新时间:2023-10-16

我创建了这个结构:

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];

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

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

sub_parts sb1;

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

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

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

一个选项是使用std::map而不是向量,然后您可以执行类似的操作

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

通过这种方式,元素"some element"answers"some other"被自动创建。

在编辑之前,您对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()也差不多。

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

我甚至故意不去深入研究引用、副本构造、智能指针、成员初始化语法,甚至classstruct的细节。这是一种太深奥的语言。尽快抽出时间,仔细阅读Bjarne Stroustrup的这篇短文,该论文在方法论上进行了明确的对比:

学习标准C++作为一种新的语言


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

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

相反:

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

在这种情况下不是特别有用,因为对象是空的。。。所以你只是推了一些没用的东西。但是,如果您的构造函数采用了填充对象的参数,那就没问题了。你甚至可以建立这样的阵列:

如何初始化构造函数需要两个或多个参数的对象数组?

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

用硬编码元素初始化std::向量最简单的方法是什么?

你可以看到,人们对不得不写有着和你一样的抱怨

std::vector<int> ints;
ints.push_back(10);
ints.push_back(20);
ints.push_back(30);

这篇文章列出了一些变通方法,但最前沿的编译器(可能不是你使用的)支持:

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

一旦你有了这些,就可以非常容易地进行"嵌套"样式的构造。


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

C++中的delete与delete[]运算符

请记住,无论如何,C++中也没有realloc。所以,如果这就是你动态分配它的原因,那就忘了这个想法。

只需将接口设为向量,就可以省去这样的麻烦。如果需要的话,你可以调整它的大小,也可以避免在程序中硬编码所谓的"幻数"。