c++重载方法参数与原始方法的参数派生类

标签 c++ inheritance overloading

我有以下对象

#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++ 在参数既是专用类又是基类时解析重载方法的方式吗?

最佳答案

首先,我看到您的函数不是虚拟的。我将假定这是有意的并且将 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);
}

总而言之——调用哪个函数是基于选择对象的表达式类型(.-> 左侧的表达式),并且只输入这将始终以这种方式工作,所以如果那是您所追求的行为,那很好。

如果你想真正重载继承的函数而不是隐藏它,你可以使用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
}

Live example

关于c++重载方法参数与原始方法的参数派生类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21877598/

相关文章:

c++ - Steady_Clock 在主游戏循环的更新之间跳过

java - 为什么对父类构造函数的调用不调用在子类中重写的父方法?

javascript - "Proper"在Javascript中继承引用值的方式?

c++ - C++ 中的运算符重载

c++ - Qt我想将一个指针编码为一个字符串,稍后再解码

c++ - 为什么 __stdcall 调用约定在 x64 中被忽略?

c++ - 无法在运行时设置 QLabel 的宽度

c++11 - 使用 GCC 在继承的模板静态成员函数上使用 decltype

java - 重载和覆盖泛型方法 - java

C++ 模板和对重载函数的模糊调用