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<<
. 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:
((Base)*this).Print(out);
slices current instance toBase
-typed temporary. That results in a direct call to base class method.((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*)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.
精彩评论