C++ virtural关键字和虚析构函数作用

来源:互联网 发布:jquery遍历json的顺序 编辑:程序博客网 时间:2024/06/01 20:39

1:到底C++中virtural关键字有什么用?

2:虚析构函数

######################################################################################################################3

虚析构函数定义作用:

虚析构函数是为了解决基类的指针指向派生类对象,并用基类的指针删除派生类对象。
如果某个类不包含虚函数,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。因为它会为类增加一个虚函数表, 使得对象的体积翻倍,还有可能降低其可移植性。

自己口述:

虚析构函数用在需要被继承的类当中,当析构new出来实例化的对象指针时(父类指向子类指针),不仅可以调用父类析构函数,同时也可调用子类析构函数。

举例:
class Person{
public:
    Person(){
        cout<<"Creat a Person!"<<endl;
    }
     ~Person(){
        cout<<"delete a person!"<<endl;
    }
};
class WangShan: public Person{
public:
    WangShan(){
        cout<<"Creat a wangshan!"<<endl;
    }
    ~WangShan(){
        cout<<"delete a wangshan!"<<endl;
    }
};
int main(){
    Person * per = new WangShan();
    delete per;
    return 0;
}
执行结果:
//只调用了父类析构函数
Creat a Person!
Creat a wangshan!
delete a person!

//在父类析构函数出加上virtual 关键字后:
virtual ~Person(){
        cout<<"delete a person!"<<endl;
  }
执行结果:
Creat a Person!
Creat a wangshan!
delete a wangshan!   //也调用了子类的析构函数。
delete a person!  

注意点:
如果不是用new在堆上实例化对象的话,直接Person per;则不需要释放内存(即不用delete per),对象自动被管理。另外没有Person  per = new WangShan();这样的写法,因为返回的是指针,变量应为指针型变量。

##############################################################################################################################3

到底C++中virtural关键字有什么用

每次都能看到网上各种争论,到底构造函数可以不可以为虚函数,析构函数可以不可以等等麻烦的规则,我想了想,下写下下面内容(不知道片面否):

virtural是为不确定的东西和特殊的某种情况而设计的,比如:

1)父类定义一个虚函数,子类去重写他,就产生多态。

2)C++多继承,如 B继承A, C也继承A, D又继承B,C,那到时候D中就会有两份A,调用时又不确定,这是引入virtual, 利用虚继承

      Class B: public virtual A , 

      Class C: public virtual A , 

然后D中就会存在一份A,实体D中有个指针指向A。

3):如果某个类要作为父类,那么它的析构函数要定义为virtual,原因是释放父类资源的时候,也会调用子类的析构函数释放资源,不然就内存泄漏。


这三种方式如何实现:这就是编译器自己的规定,它使用虚函数表来设计这种机制。

从第三点看出来,析构函数可以为虚函数,那么构造函数可以为虚函数吗,NO,原因,生成一个对象后,对象里面会存储类的数据成员和虚函数表指针,指针指向类的虚函数,如果其构造函数为虚函数,那么他也在那个虚函数表中,但是构造函数是初始化对象用的,如果将它放虚函数表里面以后也用不上,而且放里面了,初始化时也找不到他。



0 0
原创粉丝点击