Salinan dangkal dan salinan dalam
Di kelas Circle, contoh konstruktor salinan yang dijelaskan di bagian sebelumnya, strategi penyalinan konsisten dengan strategi default sistem, yaitu anggota objek asli disalin ke anggota objek baru yang sesuai secara berurutan. Dalam hal ini, mengapa kita masih ingin mendefinisikannya sendiri? Alasannya adalah menginisialisasi semua situasi dengan cara sederhana ini pasti akan menimbulkan masalah dalam situasi yang berbeda.
Misalnya, di kelas Circle tadi, jika anggota penunjuk ditambahkan ke variabel anggota dan memori perlu dialokasikan secara dinamis selama inisialisasi, akan ada risiko keamanan yang sangat besar. Kodenya adalah sebagai berikut:
/***************************************//Des: Program pendukung tutorial C++//Penulis :Huang //Hak Cipta:www.dotcpp.com//Tanggal:2017/8/26****************************** ** ******/#include<iostream>#include<Cstring>usingnamespacestd;#definePI3.1415classCircle{private:doubleR;char*str;public:Circle(doubleR,char*str);~Circle(); );doublegirth();};Lingkaran::~Lingkaran(){hapus[]str;}Lingkaran::Lingkaran(doubleR,char*str){cout<<Konstruktor<<endl;ini->R=R ;ini ->str=newchar[strlen(str)+1];strcpy(ini->str,str);cout<<ini->R<<<<ini->str<<endl;}doubleCircle::area () {returnPI*R*R;}doubleCircle::girth(){return2*PI*R;}intmain(){CircleA(5,NO.1Oldclass);CircleB(A);return0;}
Untuk memverifikasi, di kelas Circle, kami menambahkan anggota pointer dan menginisialisasinya di konstruktor tanpa konstruktor salinan khusus. Kemudian pada fungsi utama, kalimat Circle B(A); menugaskan objek A ke objek B, dan memanggil konstruktor salinan default yang dihasilkan. Setelah dijalankan, program melaporkan kesalahan seperti yang ditunjukkan di bawah ini:
Alasan sebenarnya adalah konstruktor salinan default hanya melakukan penugasan data dan tidak dapat membuka ruang memori untuk pointer, yang setara dengan kode:
Ini->str=str;
Jadi pada dasarnya, dua petunjuk menunjuk ke sepotong ruang heap. Itu bertentangan dengan niat awal kami. Kemudian di akhir program, ketika kedua objek tersebut didaur ulang, destruktornya sendiri akan dipanggil untuk melepaskan ruang memori ini karena kedua objek tersebut perlu dipanggil dua kali, yaitu dihapus dua kali, maka akan terjadi kesalahan!
Oleh karena itu, ketika ada tipe pointer di kelas, mengandalkan metode konstruktor salinan default tidak lagi dapat memenuhi kebutuhan kita. Konstruktor salinan tertentu harus ditentukan, yang tidak hanya dapat menyalin data, tetapi juga mengalokasikan ruang memori untuk anggota. untuk mencapai salinan nyata, juga disebut salinan dalam, ini adalah konstruktor salinan dalam .
Implementasi konstruktor salinan dalam:
#include<iostream>#include<Cstring>usingnamespacestd;#definePI3.1415classCircle{private:doubleR;char*str;public:Circle(doubleR,char*str);Circle(Circle&A);~Circle();doublerea(); doublegirth();};Lingkaran::~Lingkaran(){hapus[]str;cout<<CallDestructor<<endl;}Lingkaran::Lingkaran(Lingkaran&A){cout<<CopyConstructor<<endl;ini->R=AR ;ini->str=char baru[strlen(A.str)+1];strcpy(ini->str,A.str);}Lingkaran::Lingkaran(doubleR,char*str){cout<<Konstruktor<<endl ;ini->R=R;ini->str=newchar[strlen(str)+1];strcpy(ini->str,str);}doubleCircle::area(){returnPI*R*R;}doubleCircle: :girth(){return2*PI*R;}intmain(){CircleA(5,NO.1Oldclass);CircleB(A);return0;}
Prinsip implementasinya mirip dengan konstruktor dengan parameter. Ruang memori yang cukup dibuka sebelum penugasan untuk benar-benar menyelesaikan salinan lengkap. Inilah yang disebut "salinan dalam". Harap dipahami dan dicoba di komputer!