我有以下对象
#include <stdio.h>
class foo_t{ };
class bar_t: public foo_t{ };
class zoo_t: public bar_t{ };
class base_t{
public:
void dostuff(foo_t * foo){ printf("Defaulting to base\n"); };
};
class derived_t: public base_t{
public:
void dostuff(bar_t * bar){ printf("Overloading with derived\n"); };
};
int main(){
derived_t derived;
zoo_t zoo;
derived.dostuff(&zoo);
}
我看到它正在按照我的意思行事,但我希望您确认这不仅仅是巧合。
我的意思是我希望C ++解决与专业类zoo_t“接近”的方法。在这种情况下,找到的第一个祖先是bar_t,它确定调用derived_t类方法。当参数是专用类和基类时,这是C ++解析重载方法的方式吗?
答案 0 :(得分:3)
首先,我看到你的功能不是virtual
。我将假设这是有意的,并让virtual
退出讨论。
通常不会在派生类中重载基类的成员函数;你改为隐藏。这意味着base_t::dostuff
无法通过类型derived_t
的对象访问表达式访问。换句话说,这不会编译:
int main()
{
derived_t derived;
foo_t foo;
derived.dostuff(&foo);
}
然而,这将:
int main()
{
derived_t derived;
foo_t foo;
base_t& base = derived;
base.dostuff(&foo);
derived.base_t::dostuff(&foo);
}
这也有其他含义。例如,下面的代码将打印Defaulting to base
:
int main()
{
derived_t derived;
zoo_t zoo;
base_t& base = derived;
base.dostuff(&zoo);
}
总结一下 - 调用哪个函数是基于选择对象的表达式的类型(.
或->
左侧的表达式),以及该类型。< / em>那将永远都是那样的,所以如果这就是你所追求的行为,你就没事了。
如果你想真正重载继承的函数而不是隐藏它,你可以使用using
声明:
class derived_t: public base_t{
public:
void dostuff(bar_t * bar){ printf("Overloading with derived\n"); };
using bas_t::dostuff;
};
然后,以下代码将起作用:
int main()
{
derived_t derived;
foo_t foo;
bar_t bar;
zoo_t zoo;
derived.dostuff(&foo); // calls base
derived.dostuff(&bar); // calls derived
derived.dostuff(&zoo); // calss derived
}