繁体   English   中英

虚函数重载

[英]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()不会覆盖Aprint() ,因为它具有不同的签名。 因此,在第一个未编辑的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

检查你的班级定义; AB的打印功能具有不同的签名。 你打电话时

a->print();

只有一个函数适合该签名,即A::print() 如果从B的定义中删除int参数,您应该观察到您期望的行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM