gdb如何查看指针指向的是具体基类实例还是派生类实例
我们在调试过程中经常遇到类似的问题,即如何获取基类指针实际指向内存的实例是基类类型还是派生类类型,我们知道在C++中我们可以通过typeid和dynamic_cast来获取指针具体指向对象类型是基类,或者是哪个派生类。那么在gdb调试时,我们能够获取具体指向内存的类型吗?答案是可以的,我们来给出一个实例,先给出代码,文件inherit.cc:
class Animal
{
public:
Animal():animalAge(11)
{}
virtual void Foo(){
};
virtual void Boo(){
};
private:
int animalAge;
};
class Fish: public Animal
{
public:
Fish():fishAge(22){}
virtual void Foo(){
}
int fishAge;
};
class GoldFish: public Fish
{
public:
GoldFish():goldFishAge(33){}
virtual void Foo(){
}
int goldFishAge;
};
int main() {
Animal *p1 = new Animal();
Animal *p2 = new Fish();
Animal *p3 = new GoldFish();
return 0;
}
编译的时候,加上-g:
g++ -g -o inherit inherit.cc
开启调试:
gdb ./inherit
设置断点:
break 37
运行到断点:
run
如果想要获取真实类型需要输入:
set p obj on
set p pretty on
这两条指令的作用:
set p obj <on/off>: 在C++中,如果一个对象指针指向其派生类,如果打开这个选项,gdb会自动按照虚函数调用的规则显示输出(同typeid和dynamic_cast实现原理是一样的),如果关闭这个选项的话,gdb就不管虚函数表了,直接根据当前类型返回,而不会关心具体的虚函数表,这个选项默认是off。 使用show print object查看对象选项的设置。
set p pertty <on/off>: 按照层次打印结构体,on开启的话,代码会更容易读。
输入:
p p1
p p2
p p3
结果如下:
输入:
p *p1
p *p2
p *p3
结果如下:
可以看到,通过此方式我们可以正确的找到指针实际指向的类型。