我使用Clion IDE和VS Code进行C ++开发和调试,但我发现有所不同,这使我发疯。如果我有一个指向子类的指针向量,则Clion会向我显示子类的类型,而VS Code则没有。这是我可以重现效果的最简单的代码:
#include <iostream>
#include <memory>
#include <vector>
#include <string>
class A {
protected:
int x;
public:
A(int x) : x(x) {}
virtual std::string to_str() { return std::to_string(x); }
};
class B : public A {
int y;
public:
B(int x, int y) : A(x), y(y) {}
std::string to_str() override { return std::to_string(x) + '_' + std::to_string(y); }
};
class C : public A {
std::string z;
public:
C(int x, std::string z) : A(x), z(z) {}
std::string to_str() override { return std::to_string(x) + '_' + z; }
};
int main() {
std::vector<std::shared_ptr<A>> v;
v.push_back(std::make_shared<B>(2, 3));
v.push_back(std::make_shared<C>(4,"5"));
for(auto &elem : v) {
std::cout << elem->to_str() << std::endl;
}
return 0;
}
没有虚拟函数,没有有关子类的信息。 Clion和VS Code都使用相同的编译器和gdb。
在for内部放置一个断点并在gdb控制台中执行:
p *elem.get()
我得到$1 = {_vptr.A = 0x40fc70 <vtable for B+16>, x = 2}
,但是在Clion中我得到$1 = (B) {<A> = {_vptr.A = 0x40fc70 <vtable for B+16>, x = 2}, y = 3}
。
列出GDB的配置没有什么区别(相同的gdbinit),也列出漂亮的打印机有一些区别,但没有什么引人注目。
我的猜测是Clion添加了特殊的打印机,但是如果我关闭库渲染器,结果将是相同的。我也在Windows(mingw64 GCC 8.2)和Linux(GCC 7.3)上尝试过,结果相同。
我检查了GDB漂亮打印机文档,但是它不是很有用,所以我没有尝试编写它。 有专门的漂亮打印机显示子类类型和成员吗?
答案 0 :(得分:0)
为了显示对象的实际类型,CLion启用了GDB的print object
设置,这在GDB手册中描述为:
set print object set print object on
在显示指向对象的指针时,请使用虚函数表确定对象的实际(派生)类型,而不是声明的类型。请注意,虚拟功能表是必需的-此功能仅适用于具有运行时类型标识的对象;该对象的声明类型中的单个虚拟方法就足够了。
使用GDB启动调试会话时,将启用此行为,除了在CLion中的GDB控制台视图中,无法禁用它:
(gdb) set print object off