美文网首页
MFC | vector存储自定义类型(结构体 / 类)

MFC | vector存储自定义类型(结构体 / 类)

作者: 0与1的邂逅 | 来源:发表于2019-01-02 08:54 被阅读0次

    在MFC中使用vector

    在Dlg.h文件中加入

    #include<vector>
    using namespace std;
    extern vector<int> test; 
    //extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。
    //此外extern也可用来进行链接指定。
    //在这里用于定义全局变量。
    

    接着,在Dlg.cpp文件中加入

    vector<int> test; 
    
    PS:

    关于extern更多的说明,可以参考https://www.cnblogs.com/yuxingli/p/7821102.html

    往vector中push_back()类对象元素

    当用push_back()往vector插入新的元素时,出现了“尝试引用已删除的函数 ”的错误。


    为什么会出现这种错误呢?一开始的我也是百思不得其解,庆幸后来终于是解决了这个bug。
    解决方法:

    构造自定义的拷贝函数:Students::Students(const Students& s);

    #include<iostream>
    #include<vector>
    using namespace std;
    
    class Students
    {
        public:
            TCHAR sNumber[40];
            TCHAR sName[40];
            TCHAR sAge[40];
            TCHAR sSex[40];
            TCHAR sAddress[40];
            TCHAR sMath[40];
            TCHAR sCpp[40];
            Students(const Students& s);
    }; 
    
    Students::Students(const Students& s) //重载构造函数【自定义拷贝函数】 
    {
        wcscpy_s(this->sNumber, s.sNumber);
        wcscpy_s(this->sName,s.sName);
        wcscpy_s(this->sSex, s.sSex);
        wcscpy_s(this->sAge, s.sAge);
        wcscpy_s(this->sAddress, s.sAddress);
        wcscpy_s(this->sMath, s.sMath);
        wcscpy_s(this->sCpp, s.sCpp);
        
        //wcscpy_s是一个能够拷贝宽字符类型字符串的安全函数。它返回一个error_t类型的值。
        //error_t wcscpy_s(wchar_t *strDestination,size_t numberOfCharacters,const wchar_t *strSource);
        //其中strDestination为指向将要复制字符串的目的缓冲区的地址
        //numberOfCharacters为缓冲区大小(以字符计)
        //strSource为指向源字符串的指针
        
    }
    
    vector<Students>stu;
    Students s;
    stu.push_back(s); //这样,在使用push_back()时,便不会再有这个错误。 
    
    原因与总结:
    1. 往vector里面放入类对象的时候,如果对象中有用到指针变量,需要用到深拷贝。
    2. 重新申请一块内存 Students::Students(const Students & s),这就是自定义拷贝
    3. vector在调用push_back时,每次执行push_back操作,相当于底层的数组实现要重新分配大小;这种实现,体现了vector实现机制:每当push_back一个元素,都要重新分配一个大一个元素的存储,然后将原来的元素拷贝到新的存储,之后再拷贝push_back的元素,最后要析构原有的vector,并释放原有的内存
    4. 所以在vector不断地push_back()的时候,就会不断地重新申请新空间,然后把原空间的元素拷过去,然后再析构原空间的对象。
    5. 如果没有自定义拷贝函数,仅使用默认的拷贝函数,在拷贝了不同对象后 ,原对象与新对象指向的都是同一块地址,所以在连续两次析构之后,就会连续两次delete同一块内存,导致程序运行奔溃,也就出现了“尝试引用已删除的函数”这个错误。

    vector存储自定义结构体

    vector存储自定义结构体,与存储类对象类似,下面是一个简单的例子。

    #include<iostream>
    #include<vector>
    #include<algorithm>
    #include<string>
    #include<cstring>
    using namespace std;
    
    struct Student
    {
        int a;
        int b;
        string str;
    };
    
    int main()
    {
        vector<Student>stu;
        int stu_a,stu_b;
        string stu_str;
        Student s;
        s.a=1;
        s.b=3;
        s.str="My";
        stu.push_back(s); //
        s.a=4;
        s.b=2;
        s.str="YOUT";
        stu.push_back(s); //
        s.a=2;
        s.b=4;
        s.str="Tur";
        stu.push_back(s); //
        for(int i=0;i!=stu.size();i++)
        {
            cout<<stu[i].a<<'\t'<<stu[i].b<<'\t'<<stu[i].str<<endl;
        }
        return 0;
    }
    

    输出结果:


    写在最后

    哪有什么天下无Bug,只是有人在为你负重前行。加油!

    打一波广告,自己的公众号,不是技术文,主要是分享自己的一些想法,欢迎前来关注,非喜勿喷。


    我锨说

    相关文章

      网友评论

          本文标题:MFC | vector存储自定义类型(结构体 / 类)

          本文链接:https://www.haomeiwen.com/subject/ikanlqtx.html