[英]Virtual function overloading
让我们说我们有:
Class A
{
public:
virtual void print(){ std::cout<<" A "<<endl; }
}
Class B : public A
{
public:
virtual void print(int x){ std::cout<<" B "<<endl;}
}
我认为函数print的B类定义会隐藏A类的函数print。但是下面的代码工作并打印“A”
int main()
{
A * a = new B;
a->print();
return 0;
}
如果我像这样写主函数它不起作用:
int main()
{
B b;
b.print();
return 0;
}
我想知道的是...在我的第一个main()示例中,我有一个调用print()的B对象...不应该print()被隐藏并且有一个错误,就像在第二个main()示例中一样
B
的成员函数print()
不会覆盖A
的print()
,因为它具有不同的签名。 因此,在第一个未编辑的main()
版本中调用print()
时,只有一个匹配的函数可以调用,如用户juanchopanza所指出的: A::print()
。
编辑:总结:
多态行为 :如果A::print()
和B::print()
具有相同的签名,只要通过指针或引用引用对象,就会在运行时选择适当的print()
。
函数重载 :由于类是作用域而函数不跨作用域重载,因此基类中的函数被派生类中的同名函数隐藏。 为此,用于引用对象的变量类型是重要的, 而不是对象本身的类型 。 因此,在第二个示例中,您会收到一个错误,即没有匹配的函数可以调用,但在第一个示例中,只有一个函数在范围内。
这里的问题是名称查找。 在像A *a = new B; a->print()
这样的通话中A *a = new B; a->print()
A *a = new B; a->print()
编译器查看a
的类型,即A*
,并在类A
查找名为print
的成员函数。 它找到它并且它调用它。 同样, B *b = new B; b->print();
B *b = new B; b->print();
编译器在类B
查找名为print
的成员函数; 它找到了print(int)
,它不能在没有参数的情况下调用。 因为它在B
找到了一个名为print
的函数,所以它不再寻找; 它没有进入A
找到A::print()
。 那是隐藏的名字。
这里的关键是名称查找以对象的声明类型开始; 在这两个例子中,类型分别是A*
和B*
。 查找不注重实际类型的一个指针或参考点或指事。
这是因为两个print()
函数具有不同的签名。 两个功能- print()
和print(int)
被认为是不同的,并且不能被重载由彼此覆盖。
派生类中的命名重载函数隐藏了基类中的重载函数。 但是,您需要使用派生类接口来查看:
B b;
b.print(); // won't work
检查你的班级定义; A
和B
的打印功能具有不同的签名。 你打电话时
a->print();
只有一个函数适合该签名,即A::print()
。 如果从B
的定义中删除int
参数,您应该观察到您期望的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.