虚函数重载

时间:2013-12-18 07:48:47

标签: c++ polymorphism 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()示例

5 个答案:

答案 0 :(得分:6)

print()中的成员函数B未覆盖print()中的A,因为它具有不同的签名。因此,在您的第一个未编辑的print()版本中调用main()时,只有一个匹配的函数可以调用,正如用户juanchopanza所指出的那样:A::print()

编辑:总结:

  • 多态行为:如果A::print()B::print()具有相同的签名,只要您引用,就会在运行时选择相应的print()对象通过指针或引用。

  • 函数重载:由于类是作用域而函数不跨作用域重载,因此基类中的函数会被派生类中的同名函数隐藏。为此,您用来引用对象的类型的变量是重要的,不是对象本身的类型。因此,在第二个示例中,您会收到一个错误,即没有匹配的函数可以调用,但在第一个示例中,只有一个函数在范围内。

答案 1 :(得分:2)

这里的问题是名称查找。在A *a = new B; a->print()之类的调用中,编译器查看a的类型,即A*,并在类A中查找名为print的成员函数。它找到它并且它调用它。类似地,对于B *b = new B; b->print();,编译器在类B中查找名为print的成员函数;它找到print(int),不能在没有参数的情况下调用它。因为它在print中找到了一个名为B的函数,它会停止查找;它不会A进入A::print()。那是隐藏的名字。

这里的关键是名称查找以对象的声明类型开始;在这两个示例中,类型分别为A*B*。查找注意指针或引用指向或引用的事物的实际类型。

答案 2 :(得分:1)

这是因为两个print()函数具有不同的签名。两个函数 - print()print(int)被认为是不同的,并且不能被重载相互覆盖。

答案 3 :(得分:1)

派生类中的命名重载函数将这些函数隐藏在基类中。但是,您需要使用派生类接口来查看:

B b;
b.print(); // won't work

答案 4 :(得分:0)

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

a->print();

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