C++虚析构函数

  • 续isA:在函数传参时,可以使用子类对父类进行初始化,但是注意,子类中的一些父类不包含的数据成员和成员函数会丢失void fun1(Person *p) void fun2(Person &p) int main(void) Person PI; Soldier sl; funl(&pl); funl(&sl); return O; fun2(p1); fun2(s1);
  • 虚析构函数注意只是为了解决利用派生类生成父类的实例,需要父类具有虚函数,否则将有内存泄漏!
    虚析构函数是为了解决基类的指针指向派生类对象,并用基类的指针删除派生类对象。换句话说,普通的析构函数在析构IsA这种方式的对象时只能析构了父类对象而无法析构子类对象。

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

    所以基本的一条是:无故的声明虚析构函数和永远不去声明一样是错误的。实际上,很多人这样总结:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。

    抽象类是准备被用做基类的,基类必须要有一个虚析构函数,纯虚函数会产生抽象类,所以方法很简单:在想要成为抽象类的类里声明一个纯虚析构函数。
    注意,虚析构函数都是写再基类中的!
    举个例子:
    我们知道,用C++开发的时候,用来做基类的类的析构函数一般都是虚函数。可是,为什么要这样做呢?下面用一个小例子来说明(以下来自http://blog.csdn.net/liliangshuai/article/details/40425279):    
    有下面的两个类:
    class ClxBase
    {
    public:
        ClxBase() {};
        virtual ~ClxBase() {};
    
        virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; };
    };
    
    class ClxDerived : public ClxBase
    {
    public:
        ClxDerived() {};
        ~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; }; 
    
        void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
    };
    代码:
    ClxBase *pTest = new ClxDerived;
    pTest->DoSomething();
    delete pTest;
    输出结果是:
    Do something in class ClxDerived!
    Output from the destructor of class ClxDerived!
    这个很简单,非常好理解。
    但是,如果把类ClxBase析构函数前的virtual去掉,那输出结果就是下面的样子了:
    Do something in class ClxDerived!
    也就是说,类ClxDerived的析构函数根本没有被调用!一般情况下类的析构函数里面都是释放内存资源,而析构函数不被调用的话就会造成内存泄漏。我想所有的C++程序员都知道这样的危险性。当然,如果在析构函数中做了其他工作的话,那你的所有努力也都是白费力气。
    所以,文章开头的那个问题的答案就是--这样做是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。
    当然,并不是要把所有类的析构函数都写成虚函数。因为当类里面有虚函数的时候,编译器会给类添加一个虚函数表,里面来存放虚函数指针,这样就会增加类的存储空间。所以,只有当一个类被用来作为基类的时候,才把析构函数写成虚函数。
  • 虚函数使用限制
    普通函数不能是虚函数

    不能修饰静态成员函数,因为成员函数实例相关,静态函数类相关。虚函数,是一种特殊的成员函数,用来实现运行时多态的。所以静态函数不可能是虚函数。

    不能修饰内联函数,编译会通过,但是编译时会忽略内联函数,内联函数是在编译时期展开,而虚函数的特性是运行时才动态联编,所以两者矛盾,不能定义内联函数为虚函数。

    不能修饰构造函数,同样是因为在编译时会进行构造函数,而动态多态不是

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值