私はまだ共有ポインタに取り組んでいません..私はコンセプトを知っています。 XMLファイルのデータを格納する次のc ++クラスの関数をデバッグしようとしています( 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);
_
ただし、私は関数HasChildren
またはGetChildren
のみを呼び出すことができますが、Get
をgdb
から呼び出すとエラーが発生します。
_(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")
関数を実行しても問題ありません。何故ですか?共有ポインタに関する知識が限られているため、回答に説明を含めていただければありがたいです。
gdb
はコンパイラではないため、(not-so-)Niceユーザー定義型変換は行われません。 string
を必要とする関数を呼び出す場合は、const char*
ではなくstring
を指定する必要があります。
残念ながら、gdb
はコンパイラではなく、オブジェクトの作成も単純な関数呼び出しではないため、コマンドラインでstd::string
を作成することはできません。
したがって、const char*
を受け取り、std::string&
を返す小さなヘルパー関数をプログラムに追加する必要があります。ここの参照に注意してください。 gdb
はconst参照で結果を渡すことができないため、値で返すことはできません(コンパイラーではありません!)静的オブジェクトへの参照、または割り当てられたオブジェクトへの参照を返すことを選択できます。ヒープ。後者の場合、メモリリークが発生しますが、関数はデバッガからのみ呼び出されることを想定しているため、これは大きな問題ではありません。
std::string& SSS (const char* s)
{
return *(new std::string(s));
}
その後、gdb
gdb> p (paramNode_.px)->Get(SSS("domain"))
うまくいくはずです。
そのような状況で、私はコマンドを与えた後に成功しました
set overload-resolution off
以前の回答にいくつかの追加-
gdbはおそらくこのような変換を行う方法を最終的に学習するでしょう。今はできません。しかし、C++式の構文解析のサポートを改善するための活発な作業があります。
gdbもデフォルトの引数を理解しません。これは一部、gdbのバグです。また、一部はg ++のバグであり、DWARFに放出されません。 DWARFは、自明ではないデフォルトの引数を発行する方法さえ定義していないと思います。
n.m.の答えは素晴らしいですが、コードを編集して再コンパイルする必要がないようにするには、 GDBでのC++文字列の作成 で与えられた解決策を見てください。
そのソリューションでは、std::string
をヒープ上で初期化し、std::string
は、function
から呼び出したいgdb
に渡します。