继承和重载结合后,某些特性让小弟我很迷惑,求指教
继承和重载结合后,某些特性让我很迷惑,求指教
class Base{
public:
virtual void f(int);
virtual void f(double);
.......
};
void Base::f(int )
{
cout<<"Base::f(int)"<<endl;
}
void Base::f(double )
{
cout<<"Base::f(double)"<<endl;
}
class Drive:public Base{
public:
void f(complex<double>);
......
};
void Drive::f(complex<double>)
{
cout<<"Base::f(complex)"<<endl;
}
int main()
{
Base *ptr =new Drive;
ptr->f(1.0);
......
}
以上是代码,结果输出是Base::f(double),我的理解是这样的,由于派生类中定义的f重载了派生类从基类继承的两个f函数,派生类就没有这两个函数了,那么ptr->f(1.0)在派生类的作用域中没有找到形参是double的f,所以就到基类作用域中寻找,刚好找到,得出Base::f(double),
但是答案给出的解释是:重载解析只作用与静态类型(这里是Base),而不是动态类型(这里是Derive)。这句话我不能理解啊,请大家指教小弟,谢谢
另外在答案后面紧跟着一句话:同理,函数调用ptr->f(complex<double>(1.0))无法通过编译,因为在Base的接口中没有符合要求的函数,这句话我也不懂,而且让我对上一个问题更加迷惑了,求教啊,
本人分比较少,就吝啬带你点少给了,还想多问几个问题,呵呵 :)
------解决方案--------------------
这种情况叫做隐藏,不是重写,更不是重载。
------解决方案--------------------
不懂这些乱七八糟的说法,又隐藏又重写的
,果然非科班的不好跟你们交流。。。
类中的非虚函数,它的地址是在编译器编译的时候由编译器直接给出的。类中的虚函数则是通过类对象指针中的需函数表索引到的。类的继承中,子类可以覆盖掉虚函数表中父类的同名函数。若是基类指针操作子类对象,那么虚函数可以取到虚函数表中被覆盖的函数。而普通函数,是根据该指针的类型给出的(就是直接取的基类里的那个函数的地址),所以调的是鸡肋的。
------解决方案--------------------
----------------------------------------------
错误,隐藏之后就不会到基类找f了(否则还叫啥隐藏啊???)。结果之所以是Base::f(double),与隐藏没有关系,而是因为Drive中没有 virtual void f(double),导致Base中的 virtual void f(double)成为final overrider,所以就是这个结果了。你可以把Drive中的 void f(complex<double>);改为 void f( double );你会发现现在结果是Base::f(complex)了,但Base中的virtual void f(int);依然被Drive的f隐藏。
还有你贴出来的这个问题的答案也是错的,问题一展示的场景是覆盖(override),不是重载(overload)。
----------------------------------------------------
基本正确,存在的问题是override并不能说是由基类指针调用的,基类指针只是一个媒介,而overrider的选择是由动态类型通过final overrider的解析得出来的。
class Base{
public:
virtual void f(int);
virtual void f(double);
.......
};
void Base::f(int )
{
cout<<"Base::f(int)"<<endl;
}
void Base::f(double )
{
cout<<"Base::f(double)"<<endl;
}
class Drive:public Base{
public:
void f(complex<double>);
......
};
void Drive::f(complex<double>)
{
cout<<"Base::f(complex)"<<endl;
}
int main()
{
Base *ptr =new Drive;
ptr->f(1.0);
......
}
以上是代码,结果输出是Base::f(double),我的理解是这样的,由于派生类中定义的f重载了派生类从基类继承的两个f函数,派生类就没有这两个函数了,那么ptr->f(1.0)在派生类的作用域中没有找到形参是double的f,所以就到基类作用域中寻找,刚好找到,得出Base::f(double),
但是答案给出的解释是:重载解析只作用与静态类型(这里是Base),而不是动态类型(这里是Derive)。这句话我不能理解啊,请大家指教小弟,谢谢
另外在答案后面紧跟着一句话:同理,函数调用ptr->f(complex<double>(1.0))无法通过编译,因为在Base的接口中没有符合要求的函数,这句话我也不懂,而且让我对上一个问题更加迷惑了,求教啊,
本人分比较少,就吝啬带你点少给了,还想多问几个问题,呵呵 :)
------解决方案--------------------
这种情况叫做隐藏,不是重写,更不是重载。
------解决方案--------------------
不懂这些乱七八糟的说法,又隐藏又重写的
类中的非虚函数,它的地址是在编译器编译的时候由编译器直接给出的。类中的虚函数则是通过类对象指针中的需函数表索引到的。类的继承中,子类可以覆盖掉虚函数表中父类的同名函数。若是基类指针操作子类对象,那么虚函数可以取到虚函数表中被覆盖的函数。而普通函数,是根据该指针的类型给出的(就是直接取的基类里的那个函数的地址),所以调的是鸡肋的。
------解决方案--------------------
----------------------------------------------
错误,隐藏之后就不会到基类找f了(否则还叫啥隐藏啊???)。结果之所以是Base::f(double),与隐藏没有关系,而是因为Drive中没有 virtual void f(double),导致Base中的 virtual void f(double)成为final overrider,所以就是这个结果了。你可以把Drive中的 void f(complex<double>);改为 void f( double );你会发现现在结果是Base::f(complex)了,但Base中的virtual void f(int);依然被Drive的f隐藏。
还有你贴出来的这个问题的答案也是错的,问题一展示的场景是覆盖(override),不是重载(overload)。
----------------------------------------------------
基本正确,存在的问题是override并不能说是由基类指针调用的,基类指针只是一个媒介,而overrider的选择是由动态类型通过final overrider的解析得出来的。