开发者

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

开发者 https://www.devze.com 2022-12-27 00:09 出处:网络
I want to print out a derived class using the operator<<. When I print the derived class, I want to first print its base and then its own content.

I want to print out a derived class using the 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):

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;开发者_如何学Go
}

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?)


Try Base::Print(out)


To the question of why:

  1. ((Base)*this).Print(out); slices current instance to Base-typed temporary. 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.
  3. ((Base*)this)->Print(out); - I'm pretty sure this is undefined behavior.


use Base::Print instead. Virtual functions are overriden by derived class. In essence you are calling print over and over


I suggest reading C++ Primer 5th page 607 "Circumventing the Virtual Mechanism" which is a short section talking about the kind of infinite-recursion error you made.

0

精彩评论

暂无评论...
验证码 换一张
取 消