単純な「ノード」クラスの C++ コードを書いています。これは基本的に、線形リンク リストを管理するために使用されるクラスです。私は通常これを構造体で実行しますが、OOP とクラスをより適切に処理しようとしています。Nodeクラスについてこれまでに得たものは(注:Stringクラスは、典型的な「文字列」クラスの私のバージョン(トリミング)であり、コピーコンストラクタ、割り当てオーバーロード、デストラクタなどを実装しています。テストでは、うまく機能し、完全に自己完結しているようです):
class Node {
public:
//Constructor
//-----------
Node() : next_(0) {} //inline (String constructor called)
//Destructor
//----------
~Node();
//Copy Constructor
//----------------
Node(const Node &);
//Operator Overload: =
//---------------------
//In conjunction with copy constructor. Protects Class.
Node & operator=(const Node &);
private:
String relatedEntry_;
Node * next_;
};
1 つのインスタンスの作成は正常に機能しますが (つまりNode node;
、)、コピー コンストラクターを呼び出すインスタンスを作成すると、プログラムの最後でセグメンテーション違反が発生します。リンクされたリストとクラスに構造体を使用することの違いは、私には少しトリックであり、ここで何か重要なものが欠けていると思います。デフォルト コンストラクター、コピー コンストラクター、およびオーバーロードされた代入演算子の実装を次に示します。
//Constructor inlined
//Destructor
Node::~Node()
{
Node * curr = next_;
while (curr) //cycle through LL and delete nodes
{
Node * temp = curr; //hold onto current
curr = curr->next_; //increment one
delete temp; //delete former current
}
}
//Copy Constructor
Node::Node(const Node & cp)
{
std::cout << "in CopyCon" << std::endl;
relatedEntry_ = cp.relatedEntry_; //calls String class copy constructor/assignment overload
Node * curr = cp.next_; //for clarity, for traversal
while (curr) //copies related entry structure
{
Node * oldNext = next_;
next_ = new Node;
next_->next_ = oldNext; //'next' field (assign prior)
next_->relatedEntry_ = curr->relatedEntry_; //String class copy
curr = curr->next_; //increment
}
}
//OO: =
Node & Node::operator=(const Node & cp)
{
std::cout << "in OO: =" << std::endl;
if (this == &cp)
return *this; //self assignment
delete next_; //delete LL
relatedEntry_ = cp.relatedEntry_; //String Class Assignment Overload
Node * curr = cp.next_; //for clarity, for traversal
while (curr)
{
Node * oldNext = next_; //hold onto old
next_ = new Node;
next_->next_ = oldNext; //set next to old
next_->relatedEntry_ = curr->relatedEntry_; //set this string to cp string
curr = curr->next_; //increment
}
return *this;
}
オーバーロードされた割り当て関数を使用すると、実質的に同じコードであっても正常に動作するように見えることに注意してください (セグメンテーション違反はありません) 。割り当てが行わ れる前に両方のオブジェクトが既に初期化されているという事実に関係していると思いますか?
//This seems to work ok
Node node1;
Node node2;
node2 = node1;
私はこのバグで数時間過ごしたので、少し休まなければなりません。これについての洞察をいただければ幸いです。ありがとう。