在编辑之前,您“过于复杂”的担忧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 的这篇短文,该文阐述了方法论上的明显对比:
学习标准 C++ 作为一门新语言
现在我将尝试解决您的其他问题。首先,您不必在 C++ 中创建变量的命名实例来将其传递给函数。你可以重写:
sub_parts sb1;
interface[i].sb.push_back(sb1);
...相反:
interface[i].sb.push_back(sub_parts ());
在这种情况下不是特别有用,因为对象是空的......所以你只是推了一些无用的东西。但是,如果您的构造函数采用填充对象的参数,那就没问题了。你甚至可以像这样构建数组:
如何初始化其构造函数需要两个或多个参数的对象数组?
但是,如果您的构造函数采用硬编码列表(就像您的那样),那么美中不足的是有点苍蝇。虽然 C++ 可以使用您直接编码的值初始化普通数组,但传递普通数组会丢失其长度信息。向量会更好,但用硬编码值初始化它们很笨拙:
用硬编码元素初始化 std::vector 的最简单方法是什么?
你可以看到人们对不得不写的抱怨几乎和你一样:
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]
在原始数组上使用需要记住做 a delete[] interface
(而不仅仅是常规delete interface
):
C++ 中的 delete vs delete[] 运算符
请记住,C++ 中也没有 realloc。因此,如果这就是您动态分配它的原因,请忘记这个想法。
只需将 interface 设为向量,您就可以避免这样的麻烦。如果需要,您将能够调整它的大小,并且还可以避免将所谓的“幻数”硬编码到您的程序中。