informasi kontak saya
Surat[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Daftar isi
Berorientasi proses dan berorientasi objek
Pemrograman berorientasi objek
2. Kualifikasi dan enkapsulasi akses kelas
Pemrograman berorientasi proses adalah ide pemrograman yang berpusat pada proses. Dalam pemrograman berorientasi proses, program dipandang sebagai kumpulan fungsi atau prosedur yang dijalankan dalam urutan tertentu untuk menyelesaikan tugas tertentu.
keuntungan:
- Kinerja efisien : Karena pemrograman berorientasi proses secara langsung menjalankan tugas sesuai dengan proses dan tidak memerlukan pembuatan dan pengelolaan objek yang berlebihan, pemrograman ini memiliki efisiensi eksekusi yang lebih tinggi dalam beberapa skenario dengan persyaratan kinerja yang lebih tinggi, seperti pemrograman sistem yang mendasarinya, pemrograman tertanam, dll. Misalnya, dalam kernel sistem operasi, pemrograman berorientasi proses dapat digunakan untuk mengoptimalkan kinerja implementasi fungsi seperti penjadwalan proses dan manajemen memori dengan lebih baik.
- logika yang jelas : Untuk logika program yang sederhana, diimplementasikan langkah demi langkah sesuai dengan prosesnya. Struktur logika kodenya jelas dan mudah dipahami, mudah dipahami dan dipelihara. Misalnya, program sederhana yang menghitung jumlah dua angka dapat langsung mendefinisikan fungsi penghitungan menggunakan pemrograman berorientasi proses.
kekurangan:
- Pemeliharaan yang buruk : Ketika ukuran program bertambah dan fungsinya menjadi kompleks, kode berorientasi pemrograman prosedural mungkin menjadi sulit untuk dipelihara dan diperluas. Karena keterkaitan antara berbagai fungsi tinggi, modifikasi satu fungsi dapat memengaruhi fungsi terkait lainnya.
- Penggunaan kembali kode yang rendah: Penggunaan kembali kode biasanya dicapai melalui pemanggilan fungsi, tetapi untuk modul fungsional yang kompleks, penggunaan kembali lebih sulit dan fungsi tidak dapat dienkapsulasi dan diabstraksi dengan baik.
Pemrograman berorientasi objek adalah ide pemrograman yang berpusat pada objek. Objek adalah entitas yang berisi data (properti) dan metode (perilaku) untuk memanipulasi data tersebut. Dengan merangkum data dan metode terkait dalam suatu objek, integrasi data dan operasi tercapai.
keuntungan:
- Pemeliharaan yang tinggi : Merangkum fungsi dalam objek, menyembunyikan implementasi internal objek dari dunia luar, dan mengurangi sambungan antar modul. Ketika suatu fungsi perlu dimodifikasi, hanya implementasi internal dari objek terkait yang perlu dimodifikasi tanpa mempengaruhi bagian lain yang tidak terkait. Misalnya, dalam aplikasi antarmuka grafis, jika Anda ingin mengubah fungsi tombol, Anda hanya perlu mengubah metode yang sesuai dari objek tombol tanpa mempengaruhi elemen antarmuka lainnya.
- Penggunaan kembali kode yang kuat : Penggunaan kembali dan perluasan kode dapat dengan mudah dicapai melalui pewarisan, polimorfisme, dan fitur lainnya.Misalnya, membuat kelas dasar
Shape
(bentuk) dan kemudian turunkanCircle
(bulat),Rectangle
(Persegi Panjang) dan subkelas lainnya, subkelas dapat menggunakan kembali atribut dan metode kelas dasar dan membuat ekstensi tertentu.- Fleksibilitas yang baik: Pemrograman berorientasi objek mendukung polimorfisme, yang memungkinkan program untuk secara dinamis memilih dan mengeksekusi metode yang sesuai sesuai dengan tipe objek sebenarnya selama runtime, sehingga meningkatkan fleksibilitas dan skalabilitas program.
kekurangan:
- Overhead kinerja: Karena pembuatan objek, pemanggilan metode, dan operasi lainnya memerlukan sejumlah overhead, dalam beberapa skenario dengan persyaratan kinerja yang sangat tinggi, hal ini dapat memengaruhi efisiensi eksekusi program.
- Biaya belajar yang tinggi: Konsep dan fitur pemrograman berorientasi objek relatif kompleks, sehingga menyulitkan pemula untuk mempelajari dan memahaminya.
• class adalah kata kunci yang mendefinisikan kelas, Data adalah nama kelas, dan {} adalah isi kelas. Perhatikan bahwa tanda titik koma di akhir tidak dapat dihilangkan di akhir definisi kelas. Isi badan kelas disebut anggota kelas: variabel dalam kelas disebut atribut atau variabel anggota fungsi kelas dalam kelas disebut metode atau fungsi anggota kelas;
• Untuk membedakan variabel anggota, biasanya ditambahkan pengenal khusus ke variabel anggota, seperti dimulai dengan _ atau m sebelum atau sesudah variabel anggota. Perhatikan bahwa ini tidak wajib di C++, ini hanya beberapa konvensi .
• Dalam C++, struct juga dapat mendefinisikan kelas. C++ kompatibel dengan penggunaan struct di C. Pada saat yang sama, struct telah ditingkatkan menjadi sebuah kelas. Perubahan yang jelas adalah bahwa fungsi dapat didefinisikan dalam struct disarankan untuk menggunakan kelas untuk mendefinisikan kelas.
• Fungsi anggota yang didefinisikan dalam kelas bersifat inline secara default.
class Date { public: void Init(int year, int month, int day) { _year = year; _month = month; _day = day; } private: // 为了区分成员变量,⼀般习惯上成员变量 // 会加⼀个特殊标识,如_ 或者 m开头 int _year; // year_ m_year int _month; int _day; }; int main() { Date d; d.Init(2024, 3, 31); return 0; }
• Kelas mendefinisikan cakupan baru. Semua anggota kelas berada dalam cakupan kelas. Saat mendefinisikan anggota di luar kelas, Anda perlu menggunakan operator ::scope untuk menunjukkan domain kelas mana yang dimiliki anggota tersebut.
• Domain kelas mempengaruhi aturan pencarian kompilasi. Jika Init dalam program berikut tidak menentukan domain kelas Stack, kompiler akan memperlakukan Init sebagai fungsi global. Kemudian selama kompilasi, deklarasi/definisi anggota seperti array tidak dapat dilakukan ditemukan. , kesalahan akan dilaporkan. Menentukan domain kelas Stack berarti mengetahui bahwa Init adalah fungsi anggota. Jika anggota seperti array tidak dapat ditemukan di domain saat ini, maka anggota tersebut akan dicari di domain kelas.
- #include<iostream>
- using namespace std;
- class Stack
- {
- public:
- // 成员函数
- void Init(int n = 4);
- private:
- // 成员变量
- int* array;
- size_t capacity;
- size_t top;
- };
- // 声明和定义分离,需要指定类域
- void Stack::Init(int n)
- {
- array = (int*)malloc(sizeof(int) * n);
- if (nullptr == array)
- {
- perror("malloc申请空间失败");
- return;
- }
- capacity = n;
- top = 0;
- }
- int main()
- {
- Stack st;
- st.Init();
- return 0;
- }
• C++ adalah cara untuk mengimplementasikan enkapsulasi, menggunakan kelas untuk menggabungkan properti dan metode suatu objek untuk membuat objek lebih lengkap, dan secara selektif menyediakan antarmukanya kepada pengguna eksternal melalui izin akses.
• Anggota yang dimodifikasi oleh public dapat langsung diakses di luar kelas; anggota yang dimodifikasi oleh protected dan private tidak dapat diakses langsung di luar kelas, dan perbedaannya akan tercermin pada bab pewarisan nanti.
• Cakupan izin akses dimulai dari posisi munculnya penentu akses hingga muncul penentu akses berikutnya. Jika tidak ada penentu akses berikutnya, cakupan berakhir di }, yaitu kelas.
• Ketika anggota definisi kelas tidak diubah oleh kualifikasi akses, defaultnya adalah privat.
• struct defaultnya adalah publik
• Secara umum, variabel anggota akan dibatasi pada fungsi pribadi/dilindungi, dan fungsi anggota yang perlu digunakan oleh orang lain akan dipublikasikan.
Tiga karakteristik utama berorientasi objek: enkapsulasi, pewarisan, dan polimorfisme.
Pada tahap kelas dan objek, kita terutama mempelajari karakteristik enkapsulasi kelas.
Enkapsulasi: Menggabungkan data dan metode pengoperasian data secara organik, menyembunyikan properti dan detail implementasi objek, dan hanya mengekspos antarmuka untuk berinteraksi dengan objek.
Enkapsulasi pada dasarnya adalah semacam manajemen yang memudahkan pengguna untuk menggunakan kelas. Misalnya: Untuk perangkat kompleks seperti komputer, satu-satunya hal yang diberikan kepada pengguna adalah tombol daya hidup dan mati, input keyboard, monitor, jack USB, dll., yang memungkinkan pengguna berinteraksi dengan komputer dan menyelesaikan tugas sehari-hari. Namun pada kenyataannya, kerja sebenarnya dari komputer adalah CPU, kartu grafis, memori dan komponen perangkat keras lainnya.
Bagi pengguna komputer tidak perlu khawatir dengan komponen inti internalnya, seperti bagaimana tata letak sirkuit pada motherboard, bagaimana CPU dirancang, dll. Pengguna hanya perlu mengetahui cara menyalakan komputer dan cara menyalakannya. berinteraksi dengan komputer melalui keyboard dan mouse. Oleh karena itu, ketika produsen komputer meninggalkan pabrik, mereka memasang cangkang di bagian luar untuk menyembunyikan detail implementasi internal, dan hanya menyediakan sakelar daya, soket mouse dan keyboard di bagian luar sehingga pengguna dapat berinteraksi dengan komputer.
Untuk mengimplementasikan enkapsulasi dalam bahasa C++, data dan metode untuk mengoperasikan data dapat digabungkan secara organik melalui kelas, dan izin akses dapat digunakan untuk menyembunyikan detail implementasi internal objek dan mengontrol metode mana yang dapat digunakan langsung di luar kelas.
• Proses pembuatan objek dalam memori fisik menggunakan tipe kelas disebut instantiasi kelas.
• Kelas adalah deskripsi abstrak dari suatu objek. Ini seperti model, yang membatasi variabel anggota kelas. Variabel anggota ini hanya dideklarasikan dan tidak mengalokasikan ruang ketika suatu objek dipakai dengan a kelas.
• Suatu kelas dapat membuat instance beberapa objek. Objek yang dibuat menempati ruang fisik aktual dan menyimpan variabel anggota kelas. Misalnya: membuat instance objek dari suatu kelas seperti menggunakan gambar desain arsitektur untuk membangun rumah di dunia nyata. Kelas itu seperti gambar desain. Gambar desain merencanakan berapa banyak ruangan yang ada, ukuran dan fungsi ruangan, dll., tetapi ada bukanlah suatu benda fisik. Sekalipun suatu bangunan ada, ia tidak dapat menampung orang. Hanya jika sebuah rumah dibangun dengan menggunakan gambar desain, maka rumah tersebut dapat dijadikan tempat tinggal. Kelas yang sama seperti gambar desain dan tidak dapat menyimpan data. Objek yang dipakai mengalokasikan memori fisik untuk menyimpan data.
Analisis anggota apa saja yang ada di objek kelas? Setiap objek yang dipakai oleh suatu kelas memiliki ruang data independen, sehingga objek tersebut harus berisi variabel anggota. Jadi, apakah fungsi anggota disertakan? Pertama, setelah fungsi dikompilasi, itu adalah bagian dari instruksi, yang tidak dapat disimpan dalam objek. Instruksi ini disimpan dalam area terpisah (segmen kode), jadi jika harus disimpan dalam objek, maka hanya dapat disimpan pointer ke fungsi anggota. Mari kita analisis lagi, apakah perlu menyimpan pointer di objek? Tanggal membuat instance dua objek d1 dan d2. Baik d1 dan d2 memiliki variabel anggota independen _tahun/_bulan/_hari untuk menyimpan datanya sendiri, tetapi fungsi anggota Init/Print pointer dari d1 dan d2 adalah sama, jadi menyimpannya dalam objek akan sia-sia. Jika Anda menggunakan Date untuk membuat instance 100 objek, maka penunjuk fungsi anggota akan disimpan 100 kali, yang terlalu boros. Faktanya, penunjuk fungsi tidak perlu disimpan. Penunjuk fungsi adalah sebuah alamat. Fungsi pemanggil dikompilasi menjadi instruksi perakitan [alamat panggilan]. Faktanya, kompiler harus menemukan alamat fungsi tersebut saat mengkompilasi dan menghubungkan , bukan saat runtime. Hanya polimorfisme dinamis yang ditemukan saat runtime, dan alamat fungsi perlu disimpan.
Di atas kami menganalisis bahwa hanya variabel anggota yang disimpan dalam objek. C++ menetapkan bahwa objek yang dipakai oleh kelas juga harus mematuhi aturan penyelarasan memori.
Aturan penyelarasan memori
Aturan penyelarasan memori sama persis dengan aturan dalam bahasa CArtikel referensi:Bahasa C untuk menghitung penyelarasan memori
Anggota pertama berada pada alamat offset 0 dari struktur.
• Variabel anggota lainnya harus dipetakan ke alamat yang merupakan kelipatan bilangan bulat dari suatu bilangan tertentu (bilangan penyelarasan).
• Catatan: Logaritma = yang lebih kecil antara nomor penyelarasan default compiler dan ukuran anggota.
•Logaritma default di VS adalah 8
• Ukuran total struktur adalah: kelipatan bilangan bulat dari jumlah penyelarasan maksimum (yang terbesar dari semua jenis variabel dan parameter penyelarasan default terkecil).
• Jika suatu struktur disarangkan dan struktur yang disarangkan tersebut disejajarkan dengan kelipatan bilangan bulat dari logaritma maksimumnya, maka ukuran keseluruhan dari struktur tersebut adalah jumlah penyelarasan maksimum dari seluruh nomor (termasuk penyelarasan struktur yang disarangkan).
Jika tidak ada variabel anggota maka harus diberikan 1 byte, karena jika tidak diberikan satu byte pun, bagaimana dapat menunjukkan bahwa objek tersebut ada? Jadi 1 byte diberikan di sini murni untuk identifikasi placeholder keberadaan objek.
Ada dua fungsi anggota, Init dan Print, di kelas Date. Tidak ada perbedaan antara objek yang berbeda di badan fungsi. Jadi ketika d1 memanggil fungsi Init dan Print, bagaimana fungsi tersebut mengetahui apakah ia harus mengakses objek d1 atau objek d2?Kemudian di sini kita akan melihat bahwa C++ memberikan pointer ini secara implisit untuk menyelesaikan masalah di sini.
• Setelah kompiler dikompilasi, fungsi anggota kelas akan menambahkan pointer dari tipe kelas saat ini, yang disebut pointer ini, ke posisi pertama parameter formal secara default. Misalnya, prototipe sebenarnya dari kelas Init of Date adalah,void Init(Tanggal* const ini, int tahun, int bulan, int hari) • Saat mengakses variabel anggota dalam fungsi anggota kelas, variabel tersebut pada dasarnya diakses melalui penunjuk ini, misalnya, saat memberikan nilai ke _tahun dalam fungsi Init, ini - >_tahun = tahun;
• C++ menetapkan bahwa pointer ini tidak dapat ditulis secara eksplisit pada posisi parameter aktual dan parameter formal (kompiler akan menanganinya selama kompilasi), tetapi pointer ini dapat digunakan secara eksplisit di badan fungsi.
- #include<iostream>
- using namespace std;
- class Date
- {
- public:
- // void Init(Date* const this, int year, int month, int day)
- void Init(int year, int month, int day)
- {
- // 编译报错:error C2106: “=”: 左操作数必须为左值
- // this = nullptr;
- // this->_year = year;
- _year = year;
- this->_month = month;
- this->_day = day;
- }
- void Print()
- {
- cout << _year << "/" << _month << "/" << _day << endl;
- }
- private:
- // 这⾥只是声明,没有开空间
- int _year;
- int _month;
- int _day;
- };
- int main()
- {
- // Date类实例化出对象d1和d2
- Date d1;
- Date d2;
- d1.Init(2024, 7, 1); // d1.Init(&d1, 2024, 7, 1);
- d1.Print(); // d1.Print(&d1);
- d2.Init(2024, 7, 10); // d2.Init(&d2, 2024, 7, 10);
- d2.Print(); // d2.Print(&d2);
- return 0;
- }