在没有new关键字的情况下创建的c ++中结构对象的范围
Scope of struct object in c++ created without new keyword
来自 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;
}
是的,info
会在循环结束时销毁。 push_back
从 info
创建一个新的副本,所以即使 info
被破坏,它的副本仍然存在于向量中。
你是正确的,info
对象将被销毁,但在使用 push_back
时它被 复制 到向量中。其余代码从向量中读取副本而不是原始对象。
http://www.cplusplus.com/reference/vector/vector/push_back/
复制是使用对象的复制构造函数完成的,在本例中,它是由编译器提供的。它将依次调用结构的字符串和向量成员的复制构造函数。
变量的范围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;
}
当push_back是完毕。如果您可以为 Student_info 编写自定义复制构造函数并在那里打印一些内容,您将看到复制构造将被调用。
考虑使用,
http://en.cppreference.com/w/cpp/container/vector/emplace_back
来自 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;
}
是的,info
会在循环结束时销毁。 push_back
从 info
创建一个新的副本,所以即使 info
被破坏,它的副本仍然存在于向量中。
你是正确的,info
对象将被销毁,但在使用 push_back
时它被 复制 到向量中。其余代码从向量中读取副本而不是原始对象。
http://www.cplusplus.com/reference/vector/vector/push_back/
复制是使用对象的复制构造函数完成的,在本例中,它是由编译器提供的。它将依次调用结构的字符串和向量成员的复制构造函数。
变量的范围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;
}
当push_back是完毕。如果您可以为 Student_info 编写自定义复制构造函数并在那里打印一些内容,您将看到复制构造将被调用。 考虑使用, http://en.cppreference.com/w/cpp/container/vector/emplace_back