来自Java背景,以下代码令我感到困惑。这里的困惑是没有new
关键字的C ++对象创建。我正在创建此对象Student_info info;
,然后将其添加到向量中。由于我不使用new关键字创建它,它是否会在堆栈上分配并在循环退出后被销毁?如果是这种情况,最后一个循环如何能够正确地从向量中提取信息?不应该抛出异常,因为添加到向量中的所有对象都已被破坏了吗?
struct Student_info {
string name;
vector<double> marks;
};
int main()
{
int num = 2;
vector<Student_info> student_infos;
for (int i = 0; i < 3; i++) {
Student_info info; //will this object be destroyed once this loop exits?
cout << "Enter name:";
cin >> info.name;
double x;
cout << "Enter 2 marks";
for (int j = 0; j < num; j++) {
cin >> x;
info.marks.push_back(x);
}
student_infos.push_back(info);
}
for (int i = 0; i < 3; i++) {
cout << student_infos[i].name;
for (int j = 0; j < num; j++) {
cout << student_infos[i].marks[j];
}
cout << endl;
}
return 0;
}
答案 0 :(得分:3)
你是正确的,info
对象将被销毁,但在使用push_back
时被复制。其余代码从向量而不是原始对象读取副本。
http://www.cplusplus.com/reference/vector/vector/push_back/
使用对象的复制构造函数完成复制,在这种情况下,复制构造函数是编译器提供的。它将依次调用结构的字符串和向量成员上的复制构造函数。
答案 1 :(得分:3)
变量info
的范围是从声明变量开始的for语句的块范围。
for (int i = 0; i < 3; i++) {
Student_info info; //will this object be destroyed once this loop exits?
//...
}
每次执行循环的新迭代时,都会创建一个名为info的新对象。
变量student_infos
的范围是函数main的最外部块范围,其中声明了变量。
int main()
{
vector<Student_info> student_infos;
//...
}
执行循环时,会将新对象添加到变量info
的副本中。该向量不包含对名为info
的原始对象的引用。它创建了一个对象的副本,并在内部将其存储在自身内。
考虑到通常这些循环
for (int i = 0; i < 3; i++) {
cout << student_infos[i].name;
for (int j = 0; j < num; j++) {
cout << student_infos[i].marks[j];
}
cout << endl;
}
不安全。依靠向量中的实际元素数量要好得多。你可以改写
for ( vector<Student_info>::size_type i = 0; i < student_infos.size(); i++)
{
cout << student_infos[i].name;
for ( vector<double>::size_type j = 0; j < student_infos[i].marks.size(); j++)
{
cout << student_infos[i].marks[j];
}
cout << endl;
}
答案 2 :(得分:2)
是的,info
将在循环结束时销毁。 push_back
从info
创建新副本,因此即使info
被销毁,其副本仍然存在于向量中。
答案 3 :(得分:0)
当push_back完成后,它会将临时 Student_info信息复制到 student_infos 。如果您可以为 Student_info 编写自定义复制构造函数并在那里打印某些内容,您将看到将调用复制构造。 考虑使用, http://en.cppreference.com/w/cpp/container/vector/emplace_back