如下关于继承与派生的一些问题,求解析~

这是程序
#include <iostream.h>
class B //基类
{
protected:
int x,y;
public:
B(int a=10,int b=20):x(a),y(b){ }
void calc() //基类有calc()
{
cout <<"x+y=" <<x+y <<endl;
}
};

class D: public B //公有派生类
{
protected:
int z;
public:
D(int a=1,int b=2,int c=3):B(a,b),z(c){}
void calc( ) //派生类也有calc()
{ cout <<"z+x+y=" <<z+x+y <<endl; }
};

void fn(B &t) //形参为基类的引用
{
t.calc(); //只调用基类的calc(),不会调用派生类的calc()
}

int main()
{
B Bo, *pb;
D Do;
cout<<"call Bo.calc():";
Bo.calc();
cout<<"call Do.calc():";
Do.calc();
cout<<"call Bo.calc():";
fn(Bo);
cout<<"call Do.calc():";
fn(Do);

pb=&Bo; //基类对象的指针指向基类对象
pb->calc();
pb=&Do; //基类对象的指针指向派生类对象
pb->calc();

return 0;
}
[1]请问为什么pb=&Do; pb->calc(); 他调用的函数仍然是基类的呢
[2]如果希望fn(Do);和第2条pb->calc();语句调用的是派生类的calc()函数,应该怎样修改程序?
[3]我突发奇想 把void fn(B &t) 函数 形参改为void fn(D &t) 结果发生错误 请问这是为什么呢

函数式编程
浏览 132回答 1
1回答

慕无忌1623718

你的问题是涉及到继承与覆盖的问题....c++ 重载 覆盖 隐藏的区别和执行方式成员函数被重载的特征(1)相同的范围(在同一个类中);(2)函数名字相同;(3)参数不同;(4)virtual 关键字可有可无。覆盖是指派生类函数覆盖基类函数,特征是(1)不同的范围(分别位于派生类与基类);(2)函数名字相同;(3)参数相同;(4)基类函数必须有virtual 关键字。“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)3种情况怎么执行:1。重载:看参数2。隐藏:用什么就调用什么3。覆盖:调用派生类//////////////////////////////////////////////////////////////////////也就是含有纯虚函数的基类:class A{public:virtual void f() = 0;};class B : public A{public:virtual void f(){cout < < "Hello, World! " < < endl;}};像这样,基类A中含有纯虚函数,在派生类B中实现///////////////////////////////////////////////////////////////////////////////如果某个派生类的部分或全部直接基类是从另一个共同的基类派生而来,在这些基类中,从上一级基类继承来的成员就有相同的名称,则在这个派生类中访问这个共同的基类中的成员时,可能会产生二义性,此时,可定义虚基类。这就要求在其直接基类的定义中,使用关键字virtual将那个共同的基类定义为虚基类,其语法形式如下:class 派生类名: virtual 派生方式 基类虚基类的初始化与一般的多重继承的初始化在语法上是一样的 ,但构造函数的调用顺序不同,虚基类构造函数的调用顺序是这样规定的:1)在同一层次中,先调用虚基类的构造函数,接下来依次是非虚基类的构造函数,对象成员的构造函数,派生类的构造函数。2)若同一层次中包含多个虚基类,这些虚基类的构造函数按对他们说明的先后次序调用3)若虚基类由非虚基类派生而来,则仍然先调用基类构造函数,再调用派生类构造函数。///////////////////////////////////////////////////////////////////////////////多继承体系中:class B{};class A : public B{};class C : public B{};class D : public A, public C{};A里有个B,C里也有个B,则D里会有两个B。如果class B{};class A : virtual public B{};class C : virtual public B{};class D : public A, public C{};B是A,C,以及更高层D的虚基类,此时A里有个B,C里也有个B,但D里只有一个B。-------------------------------------------------------------------------------前面是一些概念,下面是对你的一些提问进行回答(可能有误,多指教):【1】,calc(); 被基类calc();隐藏【2】,class D: virtual public B 虚基类【3】,void fn(B &t) 的形参是B &t,而形参改为void fn(D &t) 就会出错
打开App,查看更多内容
随时随地看视频慕课网APP