我有以下代码段:
using namespace std;
class base
{
public:
virtual void print(char a){ std::cout<<" Base "<<std::endl;}
};
class derived :public base
{
public:
void print(floata) {std::cout<<" Derived "<<std::endl;}
};
int main()
{
base* d = new derived;
d->print(1.5);
return 0;
}
输出为“基本” 为什么输出来自基本函数而不是衍生函数
答案 0 :(得分:1)
您尚未覆盖该基类中的函数,您已重载:该派生类中的版本以float
作为参数,与使用char
的基类方法完全不同。此外,派生类中的float
版本阴影基类版本:派生类型上的调用无法访问基类版本。
因此,以下代码
Derived d;
d.print('a');
d.print(1.5);
将打印
Derived
Derived
因为编译器将调用解析为print()
中唯一的Derived
版本。
同样,当您通过指向d->print(1.5)
的指针调用Base
时,调用将无法访问派生类的版本:编译器查看基类,发现没有{{1 }}方法使用print()
参数定义,并将其转换为float
。然后,它将调用char
的唯一实现,该实现恰好由基类提供。
如果仅更改派生类中的print(char)
方法的签名以匹配基类的签名,则奇怪的行为将消失。
答案 1 :(得分:0)
声明Base* d = new Derived;
时,类的类型为Base,由typeid(d).name()
打印,因此该实例无权访问子类方法。如果将类型更改为“派生”,则将调用子方法:
#include <iostream>
#include <typeinfo>
class Base
{
public:
virtual void print(char a) {
std::cout << " Base " << std::endl;
}
};
class Derived : public Base
{
public:
void print(float a) {
std::cout << " Derived " << std::endl;
}
};
int main()
{
Derived* d = new Derived;
std::cout << "class type is: " << typeid(d).name() << std::endl;
d->print(1.5);
return 0;
}
输出:
class type is: P7Derived
Derived
此外,声明父类print
方法virtual
不允许Base实例调用print
的子版本,因为子版本尚未覆盖它(不同的标头) )。使用Base *d = new Derived;
创建Base实例,并将Derived类中的Derived print
方法标头更改为void print(char a)
,将允许您调用子print
方法并输出{{1 }},甚至可以使用Derived
关键字从Base实例中获取。
virtual
输出:
#include <iostream>
#include <typeinfo>
class Base
{
public:
virtual void print(char a) {
std::cout << " Base " << std::endl;
}
};
class Derived : public Base
{
public:
void print(char a) {
std::cout << " Derived " << std::endl;
}
};
int main()
{
Base* d = new Derived;
std::cout << "class type is: " << typeid(d).name() << std::endl;
d->print(1.5);
return 0;
}
希望这有助于了解情况-我建议在此repl中使用不同的实例和标头来查看它们的作用。