我刚刚注意到一些奇怪的东西,当我添加"虚拟关键字"在我的类(除了构造函数之外的任何函数)中,我无法在GDB中显示我的对象的内容。 GDB说"不完整类型"
以下是代码:
//////////////// reco.h /////////////
#ifndef RECO_H
#define RECO_H
#include <iostream>
#include <string>
class reco {
public:
reco(float weight);
~reco(void);
float getWeight();
private:
float weight;
};
#endif
///////////////// reco.cpp /////////////
#include <iostream>
#include <string>
#include "reco.h"
using namespace std;
reco::reco(float weight) {
weight = weight;
}
reco::~reco(void) {
cout << "destructor reco" << endl;
}
float reco::getWeight() {
return weight;
}
////////////// main.cpp /////////////
#include <iostream>
#include <string>
#include "reco.h"
using namespace std;
int main() {
reco* s = new reco(5.0);
cout << s->getWeight() << endl;
delete s;
return 0;
}
然后使用GDB:
gdb main.exe
breakpoint main.cpp:11 <---- (cout)
run
print *s
$1 = { weight = 5 }
然后,如果我创建其中一个函数&#34; virtual&#34;,然后我重新尝试用GDB打印我的*s
指针,它会说:
&#34;不完整类型&#34;
看起来VTABLE正在发生一些事情,好像&#34;虚拟&#34;关键字隐藏了我的Reco类的实现。我知道编译器会进行后期绑定,然后VTABLE查找在运行时完成,但是在GDB调试时程序已在运行,对吗?
&#34;设置print vtbl&#34;设置在&#34; on&#34;。
如果我使用ptype s
,我会再次收到<incomplete type>
消息。
如果我使用x/540f80
检查地址,则表示&#34;无法访问内存&#34;
我不知道为什么只添加此关键字会导致我的对象类型不完整?
非常感谢你的帮助!
我注意到的最后一件事:
WITH VIRTUAL:
reco.cpp -> g0 and main.cpp -> g = incomplete type
reco.cpp -> g and main.cpp ->g = ok
没有虚拟
reco.cpp -> g0 and main.cpp -> g = ok
reco.cpp -> g and main.cpp ->g = ok
答案 0 :(得分:4)
reco.cpp -> g and main.cpp ->g = ok
假设您-> g
表示您使用reco.cpp
标记编译-g
,是执行,并且不要< / em>这样做:
g++ -c -g0 reco.cpp
您发现GCC可以优化其必须发出的调试信息的数量如果它知道您拥有key method。
没有virtual
,没有密钥方法,GCC必须将冗余调试信息发送到每个编译单元。这会使您的目标文件变大(它对最终的可执行文件几乎没有影响),但即使只使用调试信息编译了一些目标文件,也可以进行调试。