C ++:为什么我的结构向量作为一个结构?

时间:2011-01-20 14:54:07

标签: c++ vector struct

我正在通过Accelerated C ++工作,并决定搞乱那里定义的结构。在这样做时,我遇到了一个问题:创建这些结构的向量并修改每个结构中的元素似乎修改了所有结构中的元素。

我意识到这可能意味着我已经将向量中的所有结构初始化为单个内存地址的结构,但我使用.push_back()方法将“虚拟”结构插入到向量中。我的印象是.push_back()推送其参数的副本,有效地创建了一个新结构。

以下是结构的标题:

#ifndef _STUDENT_INFO__CHAPTER_9_H
#define _STUDENT_INFO__CHAPTER_9_H

#include <string>
#include <iostream>
#include <vector>

class Student_info9{
public:
    Student_info9(){homework = new std::vector<double>;};
    Student_info9(std::istream& is);

    std::string getName() const {return name;};
    double getMidterm() const {return midterm;};
    double getFinal() const {return final;};
    char getPassFail() const {return passFail;};

    std::vector<double> *getHw(){return homework;};

    void setName(std::string n) {name = n;};
    void setMidterm(double m) {midterm = m;};
    void setFinal(double f) {final = f;};


private:
    std::string name;
    double midterm;
    double final;
    char passFail;

    std::vector<double> *homework;
};


#endif  /* _STUDENT_INFO__CHAPTER_9_H */

这是我正在愚弄的代码(原谅过多的打印语句......一段时间试图调试的结果:)):

vector<Student_info9> did9, didnt9;

bool did_all_hw9(Student_info9& s)
{
    vector<double>::const_iterator beginCpy = s.getHw()->begin();
    vector<double>::const_iterator endCpy = s.getHw()->end();
    return(find(beginCpy, endCpy, 0) == s.getHw()->end());
}

void fill_did_and_didnt9(vector<Student_info9> allRecords)
{
    vector<Student_info9>::iterator firstDidnt = partition(allRecords.begin(), allRecords.end(), did_all_hw9);


    vector<Student_info9> didcpy(allRecords.begin(), firstDidnt);


    did9 = didcpy;

    vector<Student_info9> didntcpy(firstDidnt, allRecords.end());
    didnt9 = didntcpy;


}

int main(int argc, char** argv) {

    vector<Student_info9> students;

    Student_info9 record;

    for(int i = 0; i < 5; i++)
    {
        students.push_back(record);
    }

    for(int i = 0; i < students.size(); i++)
    {
        students[i].setMidterm(85);
        students[i].setFinal(90);

        students[i].getHw()->push_back(90);
        std::cout << "student[" << i << "]'s homework vector size is " << students[i].getHw()->size() << std::endl;
        students[i].getHw()->push_back(80);
        std::cout << "student[" << i << "]'s homework vector size is " << students[i].getHw()->size() << std::endl;
        students[i].getHw()->push_back(70);
        std::cout << "student[" << i << "]'s homework vector size is " << students[i].getHw()->size() << std::endl;

        std::cout << "Just pushed back students[" << i << "]'s homework grades" << std::endl;

        if(i == 3)
            students[i].getHw()->push_back(0);
    }

    std::cout << "student[3]'s homework vector size is " << students[3].getHw()->size() << std::endl;

    for(vector<double>::const_iterator it = students[3].getHw()->begin(); it != students[3].getHw()->end(); it++)
        std::cout << *it << " ";

    std::cout << std::endl;

    std::cout << "students[3] has " << ( ( find(students[3].getHw()->begin(),students[3].getHw()->end(), 0) != students[3].getHw()->end()) ? "atleast one " : "no " )
            << "homework with a grade of 0" << std::endl;

    fill_did_and_didnt9(students);


    std::cout << "did9's size is: " << did9.size() << std::endl;
    std::cout << "didnt9's size is: " << didnt9.size() << std::endl;

}

正如您在print语句中看到的那样,家庭作业成绩似乎只被添加到一个Student_info9对象中,其副本似乎填充整个向量。我的印象是,如果要在单个对象上使用.push_back()的连续副本,它将创建该对象的副本,每个副本具有不同的内存地址。

我不确定这是否是问题的根源,但希望有人可以指出我正确的方向。

感谢。

4 个答案:

答案 0 :(得分:4)

当你将StudentInfo推送到向量上时,它确实被复制了,所以这不是问题所在。问题是包含家庭作业成绩的向量。由于您只在StudentInfo中存储指向该向量的指针,因此复制StudentInfo时只会复制指针而不是向量。换句话说,你有许多不同的StudentInfos,它们都有一个指向相同作业向量的指针。

要解决此问题,您应该定义一个复制构造函数,负责复制作业向量。

答案 1 :(得分:2)

您是否了解过复制构造函数?如果是这样,请考虑vector<Student_info9> students上的push_back()发生了什么。

具体来说,这个指针会发生什么。

   std::vector<double> *homework;

答案 2 :(得分:1)

Student_info9 record;行使用第一个构造函数构造一个Student_info9。第一个构造函数创建一个向量,并将指针存储为成员变量。然后,您将继续将此Student_info9的副本添加到向量中5次。每个副本都有一个指向同一向量的指针。

答案 3 :(得分:1)

你的StudentInfo9类是指向std::vector<double>的指针,这意味着在默认的复制构造函数中(当你​​向向量添加StudentInfo9对象时将调用它),指针本身被复制了。这意味着您的所有StudentInfo9个对象都具有相同的作业向量。

这有意义吗?有关指针和复制构造函数的详细信息,请参阅http://pages.cs.wisc.edu/~hasti/cs368/CppTutorial/NOTES/CLASSES-PTRS.html