简体   繁体   English

为什么在虚函数中转换为Base类会产生分段错误?

[英]Why does this cast to Base class in virtual function give a segmentation fault?

I want to print out a derived class using the operator<< . 我想使用operator<<打印出派生类。 When I print the derived class, I want to first print its base and then its own content. 当我打印派生类时,我想首先打印它的基础,然后打印它自己的内容。

But I ran into some trouble (see segfault below): 但是我遇到了一些麻烦(见下面的segfault):

class Base {
 public:
  friend std::ostream& operator<<(std::ostream&, const Base&);
  virtual void Print(std::ostream& out) const {
    out << "BASE!";
  }
};
std::ostream& operator<<(std::ostream& out, const Base& b) {
  b.Print(out);
  return out;
}

class Derived : public Base {
 public:
  virtual void Print(std::ostream& out) const {
    out << "My base: ";
    //((const Base*)this)->Print(out); // infinite, calls this fct recursively
    //((Base*)this)->Print(out);       // segfault (from infinite loop?)                                                          
    ((Base)*this).Print(out);          // OK
    out << " ... and myself.";
  }
};

int main(int argc, char** argv){
    Derived d;
    std::cout << d;
    return 0;
}

Why can't I cast in one of these ways? 为什么我不能用其中一种方式施展?

    ((const Base*)this)->Print(out); // infinite, calls this fct recursively
    ((Base*)this)->Print(out);       // segfault (from infinite loop?)

试试Base :: Print(out)

To the question of why : 关于原因的问题:

  1. ((Base)*this).Print(out); slices current instance to Base -typed temporary. 当前实例切换为Base -typed临时。 That results in a direct call to base class method. 这导致直接调用基类方法。
  2. ((const Base*)this)->Print(out); calls virtual method through a pointer to base, which resolves to the child class method, which results in infinite recursion. 通过指向base的指针调用virtual方法,该指针解析为子类方法,从而导致无限递归。
  3. ((Base*)this)->Print(out); - I'm pretty sure this is undefined behavior. - 我很确定这是未定义的行为。

use Base::Print instead. 请改用Base::Print Virtual functions are overriden by derived class. 虚函数被派生类覆盖。 In essence you are calling print over and over 从本质上讲,你一遍又一遍地打印

我建议阅读C ++ Primer第5页第607页“绕过虚拟机制”这是一个简短的部分,讨论你所做的无限递归错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM