以下是两个重载虚函数的类:
class Base
{
public:
virtual void func(int) {
cout<<"base int"<<endl;
}
virtual void func(double) {
cout<<"base double"<<endl;
}
};
class Deri: public Base
{
public:
virtual void func(int) {
cout<<"deri int"<<endl;
}
};
我在这里使用这些类:
int main() {
Base * ptr = new Deri;
ptr->func(3.0); //"base double"
static_cast<Deri *>(ptr)->func(3.0);//"deri int"
return 0;
}
我预计这两个调用都是基本的双重超载,但我得到以下输出:
base double
deri int
当我在Deri
中添加以下“using”语句时:
using Base::func;
我从Base类中获取所有重载的函数,它按预期工作。
当我不使用“使用声明”时会发生什么?我假设ptr->func(3.0)
和static_cast<Deri*>->func(3.0)
寻找相同的vtable。但他们如何寻找不同的功能? Class Deri的vtable是什么样的?
答案 0 :(得分:0)
请看这里:http://thesyntacticsugar.blogspot.ca/2011/10/behind-scenes-name-hiding-in-c.html
它说&#34;在识别可能的候选者时,名称查找从直接范围开始向外传播。仅当没有具有正确名称的函数时,该过程才会继续到下一个封闭范围。一旦发现具有至少一个可行候选者的范围,编译器继续将参数与各种候选者的参数匹配,应用访问规则等等。
所以我的理解是名称查找开始范围的指针detemines的类型。当它是Base类的指针时,它首先在Class Base中查找。当static_cast到Deri类时,它首先在Class Deri中查找。
值得注意的是,func()的所有三个版本都在Class Deri的vtable中。