在没有新关键字

时间:2016-03-22 11:43:53

标签: c++ scope declaration

来自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;
}

4 个答案:

答案 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_backinfo创建新副本,因此即使info被销毁,其副本仍然存在于向量中。

答案 3 :(得分:0)

当push_back完成后,它会将临​​时 Student_info信息复制到 student_infos 。如果您可以为 Student_info 编写自定义复制构造函数并在那里打印某些内容,您将看到将调用复制构造。 考虑使用, http://en.cppreference.com/w/cpp/container/vector/emplace_back