美文网首页
未重写的父类函数调用已重写的函数

未重写的父类函数调用已重写的函数

作者: 李相赫的乐芙兰 | 来源:发表于2018-11-12 19:09 被阅读24次

最近在写跨服组队的功能,需要重构组队匹配的代码,在开发的过程中,遇到一个父类函数中的某一步调用需要被子类重写的问题,为了重写的函数能被正确调用,做了一下实验,结果如下:

class A{
public:
    void Foo();
    void Foo0();
    virtual void Foo1();
    void Foo2();
};

void A::Foo(){
    Foo0();
    Foo1();
}
void A::Foo0(){
    cout<<"aaa000\n";
}
void A::Foo1(){
    cout<<"aaa111\n";
}
void A::Foo2(){
    cout<<"aaa222\n";
}

class B:public A{
public:
    void Foo0();
    virtual void Foo1();
    void Foo2();
};

void B::Foo0(){
    cout<<"bbb000\n";
}
void B::Foo1(){
    cout<<"bbb111\n";
}
void B::Foo2(){
    cout<<"bbb222\n";
}

int main(){
    A tmp_a;
    B tmp_b;
    tmp_a.Foo();///aaa000 aaa111
    tmp_b.Foo();///aaa000 bbb111
    /*子类调用未重写的父类函数Foo,Foo继续调用子类已重写的函数:
    若该函数是普通函数(Foo0),则仍然调用父类的实现;若该函数是虚函数(Foo1),则调用子类的实现*/

    tmp_a.Foo2();///aaa222
    tmp_b.Foo2();///bbb222

    tmp_a = tmp_b;
    tmp_a.Foo();///aaa000 aaa111
    /*当我们用子类的对象给基类的对象赋值或者初始化基类的对象时,
    它的本质就是将从父类继承来的数据成员的值赋给父类的对象,
    而此时子类对象中的其他数据将会被截断,也就是丢失*/

    A* p_a = new B;
    p_a->Foo();///aaa000 bbb111
    /*如果用父类指针指向子类对象,
    那么父类指针也只能访问到父类所拥有的数据成员和成员函数,
    而无法访问到子类所独有的数据成员和成员函数。*/

    A& iter_a = tmp_b;
    iter_a.Foo();///aaa000 bbb111
    /*引用和指针类似*/

    return 0;
}

总结:
1.子类调用未重写的父类函数Foo,Foo继续调用子类已重写的函数:若该函数是普通函数(Foo0),则仍然调用父类的实现;若该函数是虚函数(Foo1),则调用子类的实现

2.当我们用子类的对象给基类的对象赋值或者初始化基类的对象时,它的本质就是将从父类继承来的数据成员的值赋给父类的对象,而此时子类对象中的其他数据将会被截断,也就是丢失

3.如果用父类指针指向子类对象,那么父类指针也只能访问到父类所拥有的数据成员和成员函数,而无法访问到子类所独有的数据成员和成员函数。

4.另外注意一下基类指针的回收问题。当用基类指针指向子类从堆中分配的对象时,如下形式 A*p = new B;当调用delete p;p=NULL;销毁对象时,是调用父类A的析构函数还是调用子类B的构造函数呢?如下图所示:答案是会调用父类的构造函数,这样问题就来了,子类不是从父类继承来的那些独有的成员变量的内存将得不到释放,将会造成内存泄露,这种情况应该如何避免内存泄露呢?这就需要使用虚析构函数。

虚析构函数就是在父类的析构函数前加上virtual关键字,这种特性将会被继承下去,也即子类的析构函数也为虚析构函数

虚析构函数的使用场合:当存在继承关系,用父类的指针指向从堆中分配的子类的对象时,然后又想用父类的指针去释放掉内存,就会用到虚析构函数,用了虚析构函数后,就会先调用子类的析构函数,再调用父类的构造函数了

相关文章

  • 未重写的父类函数调用已重写的函数

    最近在写跨服组队的功能,需要重构组队匹配的代码,在开发的过程中,遇到一个父类函数中的某一步调用需要被子类重写的问题...

  • Kotlin继承与多态 (1)继承

    调用父类构造函数使用主构造函数使用此构造函数重载使用参数默认值调用构造函数重写成员属性和函数重写成员属性重写成员函...

  • python-面向对象——继承

    继承 可以多层继承,子类可以直接调用父类的父类的函数 重写 调用被重写的方法: 多继承 python支持多继承 所...

  • 2020-07-07-《C++虚函数》

    虚函数可以让子类重写函数 子类重写父类中的虚函数 重写与重载的区别?

  • iOS UICollectionView预加载

    基类 重写父类实现自定义 网络请求函数需要加的设置 调用 -----end.

  • Java的重写(override)与函数转型

    Java的重写 1.函数的复写(override).2.使用super调用父类的成员函数.复写与重载是不同的.复写...

  • python oop相关

    dir del 继承父类的init以及super 未实现方法警告 继承覆盖父类函数(重写) slots 内置属性优...

  • SB或Xib布局专治代码修改frame

    重写父类函数 UIView: - (void)layoutSubviews{ [super layoutSubvi...

  • 重写要调用父类函数啊

    跟踪了层层代码,却发现调用者重写了框架方法却没有调父类,嗅觉不够灵敏啊

  • Swift 个人笔记

    在Swift中,子类可以对父类的函数进行重写。但是在重写的时候,要在函数名前加override。 而在oc中进行方...

网友评论

      本文标题:未重写的父类函数调用已重写的函数

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