30

我还没有研究过共享指针。我只知道这个概念。我正在尝试调试以下 c++ 类中的函数,该类存储 XML 文件的数据(通过xerces库读取)。

// header file
class ParamNode;
typedef boost::shared_ptr<ParamNode> PtrParamNode;

class ParamNode : public boost::enable_shared_from_this<ParamNode> {
public:
   ...
   typedef enum { DEFAULT, EX, PASS, INSERT, APPEND } ActionType;
   bool hasChildren() const;
   PtrParamNode GetChildren();
   PtrParamNode Get(const std::string&  name, ActionType = DEFAULT );
protected:
   ....
   ActionType defaultAction_;
}

现在,如果我正在调试一段代码,其中我有一个指向类的指针实例ParamNode,它被称为paramNode_

PtrParamNode paramNode_;
// read xml file with xerces
paramNode_ = xerces->CreateParamNodeInstance();
// now, the xml data is stored in paramNode_.
std::string probGeo;
// this works in the code, but not in (gdb)!!
paramNode_->Get("domain")->GetValue("gt",probGeo);
cout << probGeo << endl; // <-- breakpoint HERE

使用gdb我正在检查paramNode_对象:

(gdb) p paramNode_
$29 = {px = 0x295df70, pn = {pi_ = 0x2957ac0}}
(gdb) p *paramNode_.px
$30 = {
  <boost::enable_shared_from_this<mainclass::ParamNode>> = {weak_this_ = {px = 0x295df70, pn = {pi_ = 0x2957ac0}}}, 
  _vptr.ParamNode = 0x20d5ad0 <vtable for mainclass::ParamNode+16>, 
  ...
  name_= {...}, 
  children_ = {size_ = 6, capacity_ = 8, data_ = 0x2969798},
  defaultAction_ = mainclass::ParamNode::EX, }

并打印其成员:

(gdb) ptype *paramNode_.px
type = class mainclass::ParamNode : public boost::enable_shared_from_this<mainclass::ParamNode> {
  protected:
    ...
    mainclass::ParamNode::ActionType defaultAction_;
  public:
    bool HasChildren(void) const;
    mainclass::PtrParamNode GetChildren(void);
    mainclass::PtrParamNode Get(const std::string &, mainclass::ParamNode::ActionType);

但是,我只能调用函数HasChildrenor GetChildren,而调用Getfromgdb会导致错误:

(gdb) p (paramNode_.px)->HasChildren()
 $7 = true
 (gdb) p (paramNode_.px)->GetChildren()
 $8 = (mainclass::ParamNodeList &) @0x295dfb8: {
   size_ = 6, 
   capacity_ = 8, 
   data_ = 0x29697a8
  }
(gdb) p (paramNode_.px)->Get("domain")
 Cannot resolve method mainclass::ParamNode::Get to any overloaded instance
(gdb) set overload-resolution off
(gdb) p (paramNode_.px)->Get("domain")
 One of the arguments you tried to pass to Get could not be converted to what the function wants.
(gdb) p (paramNode_.px)->Get("domain", (paramNode_.px).defaultAction_)
 One of the arguments you tried to pass to Get could not be converted to what the function wants.

在代码中,执行该Get("domain")函数就可以了。这是为什么?由于我对共享指针的了解有限,如果您在回答中包含解释,我将不胜感激。

4

4 回答 4

32

gdb不是编译器,它不会为您进行(不太)好的用户定义类型转换。如果你想调用一个需要 a 的函数string,你需要给它 a string,而不是 a const char*

不幸的是,gdb无法std::string在命令行上为您构造一个,再次因为它不是编译器并且对象创建不是一个简单的函数调用。

所以你必须在你的程序中添加一个小辅助函数,它需要 aconst char*并返回一个std::string&. 注意这里的参考。它不能按值返回,因为那样gdb将无法通过 const 引用传递结果(它不是编译器!)您可以选择返回对静态对象的引用,或者对在堆上分配的对象的引用。在后一种情况下,它会泄漏内存,但这并不是什么大问题,因为该函数无论如何都只能从调试器中调用。

std::string& SSS (const char* s)
{
    return *(new std::string(s));
}

然后在gdb

gdb> p (paramNode_.px)->Get(SSS("domain"))

应该管用。

于 2013-05-24T13:02:16.753 回答
17

在这种情况下,我在发出命令后就成功了

set overload-resolution off
于 2015-05-02T13:29:53.950 回答
12

对上一个答案的一些补充——

gdb 可能最终会学会如何进行这样的转换。现在不能;但是在改进对 C++ 表达式解析的支持方面有积极的工作。

gdb 也不理解默认参数。这部分是 gdb 中的错误;但也部分是 g++ 中的错误,它不会将它们发送到 DWARF 中。我认为 DWARF 甚至没有定义一种发出非平凡默认参数的方法。

于 2013-05-24T20:49:23.420 回答
5

nm 的答案很好,但为了避免编辑代码和重新编译,请查看在GDB 中创建 C++ 字符串中给出的解决方案。

在该解决方案中,他们演示了std::string在堆上为 a 分配空间,然后初始化 astd::string以传递给function他们想要调用的 from gdb

于 2017-11-10T19:12:31.960 回答