これは宿題です
私は自分のC++クラスのリンクリストクラスの実装に取り組んでおり、コピーコンストラクターは非常に混乱しています。
リンクされたリストは、Elemsと呼ばれる構造体で構成されています。
struct Elem
{
int pri;
data info;
Elem * next;
};
Elem * head;
infoはElemに格納される個別のカスタムクラスです。
コピーコンストラクターの署名は次のとおりです。
linkedList::linkedList( const linkedList &v )
私が抱えている問題は、主に私のロジックを取り、実際にそれをコードとして書くことです。
私の一般的な考えは:
これは一般的な考えですか?
どんな助けでも素晴らしいでしょう。 これは宿題ですので、直接回答しないでください!
お時間をいただきありがとうございます
================================================== ================================================== ================================================== ==============
皆さん、ありがとうございました!
私はそれを理解していると思います:
//Copy Constructor
LinkedList::LinkedList( const LinkedList &v )
{
Elem * p1 = 0;//current
Elem * p2 = 0;//next
if( v.head == 0 )
head = 0;
else
{
head = new Elem;
head -> pri = v.head -> pri;
head -> info = v.head -> info;
p1 = head;
p2 = v.head -> next;
}
while( p2 )
{
p1 -> next = new Elem;
p1 = p1 -> next;
p1 -> pri = p2 -> pri;
p1 -> info = p2 -> info;
p2 = p2 -> next;
}
p1 -> next = 0;
}
私はそれがうまくいくと確信しています。私は助けるためにいくつかの論理的な絵を描きました、そして、私はどんな問題にも遭遇しませんでした。
ステップ1とステップ2の一部に注意する必要があります。ステップ1で新しいノードを割り当て、それをhead
として使用する必要があります。ステップ2では、next = v.next
、あなたの意図が浅いコピーを作成することでない限り、正しくありません。
リンクされたリストなどのコンテナをコピーする場合、おそらく深いコピーが必要になるため、新しいノードを作成してデータのみをコピーする必要があります。新しいリストのノードのnext
およびprior
ポインタは、そのリストに対して作成した新しいノードを特定してからのノードではなく、元のリスト。これらの新しいノードには、元のリストからの対応するデータのコピーがあるため、新しいリストは値ごと、またはディープコピーと見なすことができます。
以下は、浅いコピーと深いコピーの違いを描いた画像です。
図のDeep Copy部分で、どのノードも古いリストのノードをポイントしていないことに注意してください。浅いコピーと深いコピーの違いの詳細については、ウィキペディアの記事 オブジェクトのコピー を参照してください。
this->head = v.head
は設定しないでください。頭は単なるポインタだからです。新しいヘッドを作成し、v.head
から新しいヘッドに値を個別にコピーする必要があります。それ以外の場合は、同じものを指す2つのポインターがあります。
次に、v.head
で始まる一時的なElem
ポインターを作成し、リストを反復処理して、その値を新しいElem
ポインターにコピーして、新しいコピーにする必要があります。
上記を参照。
コピーコンストラクターは何をコピーする必要がありますか? pri
をコピーする必要があります-簡単です。 info
-も簡単にコピーできます。そして、next
がnullでない場合は、それもコピーする必要があります。 next
をコピーするにはどうすればよいですか?再帰的に考える:まあ、next
はElem *
、およびElem
にはコピーコンストラクターがあります。これを使用して、参照されているElem
をコピーし、参照するだけです。
これを反復的に解決することもできますが、再帰的ソリューションの方がはるかに直感的です。
だからここに私の答えがあります(それがあなたの宿題に合うかどうかわからない-インストラクターは時々独自のアイデアを持っている傾向があります;):
通常、コピーコンストラクターはオブジェクトを「コピー」する必要があります。つまりlinkedList l1があり、linkedList l2 = l1(linkedList :: linkedList(l1)を呼び出す)を実行するとします。l1とl2は、l1の変更がl2に影響を与えず、その逆も同様であるという意味で、完全に別個のオブジェクトです。
ポインターを割り当てるだけでは、実際のコピーは得られません。どちらかを逆参照して変更すると、両方のオブジェクトに影響するためです。
ソースリスト内のすべての要素の実際の詳細なコピーを作成したい場合(または、ファンシーになりたい場合は、オンデマンドコピーのみを実行する場合)。
行を忘れましたreturn;
後
if( v.head == 0 )
head = 0;
外に出る必要がありますよね?