通过基类虚函数获取派生类型 [英] Get derived type via base class virtual function

查看:190
本文介绍了通过基类虚函数获取派生类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过一个基类虚函数来获得一个对象的派生类型。我写了这个,不编译:

I am trying to get the derived type of an object via a base class virtual function. I have written this, which does not compile:

struct base {
  virtual base& get_this() {
    return *this;
  }
};

struct derived : base {
  virtual derived& get_this() override {
    return *this;
  }

  void fn();
};


int main () {
  base* pd = new derived();
  derived& x = pd->get_this(); /*ERROR*/
  x.fn();
  return 0;
}

...给我一个错误:我不能初始化一个 derived& base 。由于 get_this 是虚拟的,为什么 pd-> get_this()返回 而不是派生& ?提前感谢!

... giving me an error that: I cannot initialize a derived& from a base. Since get_this is virtual, why does pd->get_this() return a base& instead of a derived&? Thanks in advance!

编辑:

感谢大家的实用答案,我应该在原始帖子中指定,我也有兴趣解决我的问题,而不是只是弄清楚为什么上面的不编译。我的主要问题是 fn 对于派生的类是唯一的,不能通过基类调用。使用casts肯定解决了问题,但我讨厌编写代码与if的结构只是为了获得正确的类型(也是斯科特梅耶斯建议反对casts :))。答案似乎表明,演员是要走的路,这在某种程度上至少令人放心,我不忽略一个更优雅的解决我的问题。再次感谢!

Thanks everyone for their useful answers and apologies for my late reply. I should have specified in the original post that I am also interested in a solution to my problem rather than just figuring out why the above does not compile. My main problem is that fn is unique to the derived class and cannot be called via the base class. Using casts sure solves the problem but I hate writing code with if else constructs just to get the right type (also Scott Meyers advise against casts :)) . The answers seem to indicate that casts are the way to go, which in a way is at least reassuring that I am not neglecting a more 'elegant' solution to my problem. Thanks again!

推荐答案

C ++协变返回类型支持只会工作,只要你已经知道派生类型。要将基类向下转换为可能的派生类,只需使用 dynamic_cast< derived>(base_ref) 以确定base_ref是否与实际派生类型匹配:

C++ covariant return types support will only work, as long you already know the derived type. To downcast a base class to a possibly derived class, simply use dynamic_cast<derived>(base_ref) to determine if base_ref matches the actual derived type:

int main () {
    base* pd = new derived();
    derived& x = dynamic_cast<derived&>(*pd); // Will throw an exception if pd 
                                          // isn't a 'derived'
    x.fn();
    return 0;
}

或者:

int main () {
    base* pd = new derived();
    derived* x = dynamic_cast<derived*>(pd); // Will return nullptr if pd isn't
                                         // a 'derived'
    if(x) {
        x->fn();
    }
    else {
        // dynamic_cast<derived*> failed ...
    }
    return 0;
}

支持派生类的协变返回类型,但是其他答案描述你不能通过调用基类

c++ supports covariant return types for derived classes, but as the other answers describe you cannot get it via calling the base class (pd->get_this()) here.

您还可以考虑使用 pd-> get_this ://en.wikipedia.org/wiki/Curiously_recurring_template_pattern#Static_polymorphism>静态多态性,以便在编译时检查类型合规性,如果您不能使用 RTTI ,异常处理或需要紧密类型绑定(无vtable开销)。

You might also consider static polymorphism to check type compliance at compile time, if you can't use RTTI, exception handling or want tight type binding (without vtable overhead).

这篇关于通过基类虚函数获取派生类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆