我想使用operator<<
打印出派生类。当我打印派生类时,我想首先打印它的基础,然后打印它自己的内容。
但我遇到了一些麻烦(见下面的段错误):
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;
}
为什么我不能用其中一种方式投射?
((const Base*)this)->Print(out); // infinite, calls this fct recursively
((Base*)this)->Print(out); // segfault (from infinite loop?)
答案 0 :(得分:6)
尝试Base :: Print(out)
答案 1 :(得分:4)
关于为什么:
的问题((Base)*this).Print(out);
切片当前实例到Base
- 输入临时。这导致直接调用基类方法。((const Base*)this)->Print(out);
通过指向base的指针调用虚方法,该指针解析为子类方法,从而导致无限递归。((Base*)this)->Print(out);
- 我很确定这是未定义的行为。答案 2 :(得分:2)
使用Base::Print
代替。虚函数被派生类覆盖。
实质上,你一遍又一遍地打电话打印
答案 3 :(得分:0)
我建议阅读C ++ Primer第5页第607页“绕过虚拟机制”这是一个简短的部分,讨论你所做的无限递归错误。