C++ 容器存储对象指针时的析构用法

续上一篇《C++模板类(泛型类)学习总结》(网址:http://www.cnblogs.com/sharpstill/archive/2012/01/27/2330059.html)现在问题来了,我建立了一个MotherStudent<Student*>* mother_std 的指针,我想要析构这个MotherStudent里的children(vector<T>,该T是一个Student*指针),我如何析构一个装满指针的容器?
贴出上次修改过的博文里的代码如下:(注意红笔)
int _tmain(int argc, _TCHAR* argv[]){
    // MotherStudent<Student*> mother_std_obj;//这一句话问题来了,由于我加入了显示的delete mother_std,编译器系统自动调用一下析构函数会 发生在这个函数调用结束后,这样调用两次析构就有问题了,所以注释了。下一句话也改为new了
    MotherStudent<Student*>* mother_std =new MotherStudent<Student*>(); //请注意这里的写法,不能写MotherStudent<Student>*  mother_std = .. 因为C++中如果写Student是抽象类(含纯虚函数),这样会尖括号中直接写类名会用无参构造函数构造这个类的,然后报错:“抽象类不能实例化”,所以这里用指针了。
    vector<Student*> *children = new vector<Student*>();
    for(int i = 0;i<4;i++){ //这个妈妈学生对象的children成员装入四个CollegeStudent对象(该对象也是继承自Student类的,所以可以装入)
        //这是int转换成string的标准方法
        stringstream strm;
        strm<<i;
        string name = "乔布斯" + strm.str()+"号";
        //CollegeStudent构造函数2个参数,age和name
        Student* per = new CollegeStudent(i,name); //因为模板类那里定义成了指针的,所以该模板类的T是Student*指针,所以里面的children成员变量也是包含指针的vector集合。
        children->push_back(per); //注意:这里装的是“父类引用指向子类对象”的Student指针,子类为CollegeStudent
    }
   
    mother_std->setChildren(*children); //setChildren方法的形参是定义成“引用”的了,所以这里传入的是“解引用符号"解的指针。
    for(vector<Student*>::iterator iter=mother_std->getChildren().begin();iter!=mother_std->getChildren().end();iter++){
        //iter是得到"指向Student*的指针",所以(*iter)得到Student*,然后->name,访问name
        std::cout << "name is " <<(*iter)->name<< " age is " << (*iter) ->getAge() << std::endl;
    }
    //增加的一句,调用这个MotherStudent的析构函数,该析构函数内部遍历children的vector,挨个delete指针,这样达到析构目的
    delete mother_std;
}   
//client调用程序结束
//贴出MotherStudent内部的析构函数代码,安全方式
    ~MotherStudent(){
        for(vector<T>::iterator iterator= this->children->begin();iterator!=this->children->end();iterator++){
            if(*iterator!=NULL){//判断不是等于NULL再delete
            delete (*iterator);
//这一句最终调用的是Student的析构函数,经过vs2008的实验,会先调用Student父类的析构函数,再调用子类CollegeStudent的析构函数,当然这一切基于父类Student的析构声明为virtual。这是一种良好的工程实践做法,因为只析构父类则会把子类 extend的那部分没有析构,造成内存泄露,具体内容详见“摘抄网上”的一楼
            *iterator=NULL;
            }
        }
        this->children->clear();//最后clear一下
    }

posted @ 2012-01-27 11:11  sharpstill  阅读(2393)  评论(1编辑  收藏  举报