我创建了这个结构:
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
。这导致必须创建大量变量才能在我的结构中输入单个值。
答案 0 :(得分:0)
在编辑之前,您对push_back()
“过于复杂”的担忧并不明确。 (听起来好像甚至你不喜欢这个方法的名字......还是那种奇怪的东西?)
我会尝试解决提出的新问题。但我要重申,尽管您使用的是标准库string
和vector
类,但您的结构本身并不具备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”。