来自新世界:关于子类父类的同名函数

之前我一直以为若子类的公有函数要和父类同名只能加个virtual,事实上不是的:

#include <iostream>
using namespace std;
class A{
    private:
      int i;
    public:
    A(int j):i(j){}
    void show(){
        cout << "this is A:" << i << endl;
    }
};
class B:public A{
    private:
      int k;
    public:
    B(int o,int p):A(o),k(p){}
    void show(){
        cout << "this is B:" << k << endl;
    }
    void hello(){
        cout << "fuck" << endl;
    }

};
int main(){
    A y(5);
    B x(5,5); 
    A *p = &x;   //派生类指针不能指向基类
    //y.show();
    //x.A::show();
    p->show();   //加了virtual就调用派生类(B)的show函数
    ((B *)p)->show();
}

 

 

这时我们可以发现,即使基类指针指向派生类,调用的依旧是父类的函数,而非像加了virtual那样子的调用子类版本的show(),但是当指针被强制转换为子类指针时才可以调用子类的函数。想要用基类指针调用不同的版本的函数,就要在父类的show()前加一个virtual。

然鹅我突然想到,为什么这两个show函数不会冲突呢?其实这两个函数不在同一个作用域里面,C++会先去子类中搜索要用的函数,找不到再去父类里面找,因此如果要在子类对象里面调用父类函数,可以在子类对象中使用解析符 :: 去调用基类方法。

int main(){
    A y(5);
    B x(5,5); //派生类指针不能指向基类
    A *p = &x;
    y.show();
    x.A::show();
}

最后来个汇总:

#include <iostream>
using namespace std;
class A{
    private:
      int i;
    public:
    A(int j):i(j){}
    void show(){
        cout << "this is A:" << i << endl;
    }
};
class B:public A{
    private:
      int k;
    public:
    B(int o,int p):A(o),k(p){}
    void show(){
        cout << "this is B:" << k << endl;
    }
    void hello(){
        cout << "fuck" << endl;
    }

};
int main(){
    A x(5);
    B y(5,5);
    //B *pt = &x;   派生类指针不能指向基类
    A *pi = &x;
    B *p = &y;
    pi->show();
    ((B *)pi)->show();   //将基类指针强制转换为派生类指针
    ((B *)pi)->hello();
    //p = &x;      报错,派生类不可以指向基类
    p->hello();
    p->show();
    ((A *)p)->show();       //将派生类指针强制转换为基类指针
    //y.show();
    //x.A::show();
}

结果:

 

 

(第二个由于没有默认构造一个B类,也就是没用构造好B类的部分,因此B类的私有成员值会变成一串无意义的数字)

发布者

我乃堂堂SCUT的一条咸鱼!

发表评论

电子邮件地址不会被公开。 必填项已用*标注