it-swarm-id.com

Membuat konstruktor salin untuk daftar tertaut

Ini adalah pekerjaan rumah

Saya sedang berupaya menerapkan kelas daftar tertaut untuk kelas C++ saya, dan pembuat salinan sangat membingungkan bagi saya.

Daftar tertaut terdiri dari struct yang disebut Elems:

struct Elem 
    {
        int pri;
        data info;
        Elem * next;
    };
    Elem * head;

info adalah kelas khusus dan terpisah yang disimpan di Elem.

tanda tangan untuk pembuat salinan adalah:

linkedList::linkedList( const linkedList &v )

Masalah yang saya alami sebagian besar mengambil logika saya dan benar-benar menulisnya sebagai kode.

Ide umum saya adalah:

  1. Tetapkan head ke v.head (head = v.head)
  2. Tetapkan nilai Elem ke v's (pri = v.pri, info = v.info, next = v.next)
  3. Ulangi, ulangi langkah 2.

Apakah ini ide umum?

Bantuan apa pun akan bagus. Ingat, ini adalah pekerjaan rumah, jadi tolong jangan jawab langsung!

Terima kasih atas waktu Anda

================================================== ================================================== ================================================== ==============

Terima kasih untuk waktunya, semuanya!

Saya pikir saya sudah tahu:

//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;
}

Saya cukup yakin itu berhasil. Saya menggambar beberapa gambar logis untuk membantu, dan saya tidak mengalami masalah apa pun.

20
Joshua

Anda harus berhati-hati dengan Langkah 1 dan bagian dari Langkah 2. Langkah 1 harus mengalokasikan simpul baru dan menggunakannya sebagai head. Pada Langkah 2, bagian tentang next = v.next, kecuali maksud Anda adalah membuat salinan yang dangkal, salah.

Saat Anda menyalin wadah seperti daftar yang ditautkan, Anda mungkin menginginkan salinan yang dalam, jadi simpul baru harus dibuat dan hanya data yang disalin. Pointer next dan prior di node daftar baru harus merujuk ke node baru yang Anda buat khusus untuk daftar itu dan bukan node dari daftar asli. Node baru ini akan memiliki salinan data yang sesuai dari daftar asli, sehingga daftar baru dapat dianggap sebagai nilai, atau salinan dalam.

Ini adalah gambar yang menggambarkan perbedaan antara penyalinan yang dangkal dan dalam:

enter image description here

Perhatikan bagaimana di bagian Salin Jauh diagram, tidak ada titik yang menunjuk ke titik di daftar lama. Untuk informasi lebih lanjut tentang perbedaan antara salinan dangkal dan dalam, lihat artikel Wikipedia di penyalinan objek .

21
  1. Anda seharusnya tidak mengatur this->head = v.head. Karena kepala hanyalah sebuah pointer. Yang perlu Anda lakukan adalah membuat kepala baru dan menyalin nilai satu per satu dari v.head ke kepala baru Anda. Kalau tidak, Anda akan memiliki dua petunjuk menunjuk ke hal yang sama.

  2. Anda kemudian harus membuat pointer Elem sementara yang dimulai dengan v.head dan beralih melalui daftar, menyalin nilainya ke pointer Elem baru ke dalam salinan baru.

  3. Lihat di atas.

4
Zeenobit

Apa yang harus Anda salin dari konstruktor? Itu harus menyalin pri - mudah. Seharusnya menyalin info- mudah juga. Dan jika next bukan nol, itu juga harus menyalinnya. Bagaimana Anda bisa menyalin next? Pikirkan rekursif: Ya, next adalah Elem *, dan Elem memiliki copy constructor: Gunakan saja untuk menyalin Elem yang direferensikan dan merujuk padanya. 

Anda juga bisa menyelesaikannya secara berulang, tetapi solusi rekursif jauh lebih intuitif.

2
Landei

Jadi, inilah jawaban saya (tidak tahu apakah itu cocok dengan pekerjaan rumah Anda atau tidak - instruktur kadang-kadang memiliki ide sendiri;):

Umumnya copy constructor harus "menyalin" objek Anda. Yaitu. katakanlah Anda memiliki linkedList l1, dan lakukan linkedList l2 = l1 (yang memanggil linkedList :: linkedList (l1)), kemudian l1 dan l2 adalah objek yang sepenuhnya terpisah dalam arti bahwa modifikasi l1 tidak mempengaruhi l2 dan sebaliknya.

Ketika Anda hanya menetapkan pointer Anda tidak akan mendapatkan salinan nyata, karena dereferencing dan memodifikasi salah satu dari mereka akan mempengaruhi kedua objek. 

Anda lebih suka membuat salinan nyata dari setiap elemen dalam daftar sumber Anda (atau hanya melakukan copy-on-demand, jika Anda ingin menjadi mewah).

0
cli_hlt

Anda lupa baris return; Setelah

if( v.head == 0 )
    head = 0;

Anda harus keluar, kan?

0
andy