Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Kelas abstrak bertindak sebagai ekspresi konsep umum tempat kelas yang lebih spesifik dapat diturunkan. Anda tidak dapat membuat objek dari jenis kelas abstrak. Namun, Anda dapat menggunakan pointer dan referensi untuk jenis kelas abstrak.
Anda membuat kelas abstrak dengan mendeklarasikan setidaknya satu fungsi anggota virtual murni. Itu adalah fungsi virtual yang dideklarasikan dengan menggunakan sintaks penentu murni (= 0). Kelas yang berasal dari kelas abstrak harus mengimplementasikan fungsi virtual murni atau juga merupakan kelas abstrak.
Pertimbangkan contoh yang disajikan dalam Fungsi virtual. Niat kelas Account adalah untuk menyediakan fungsionalitas umum, tetapi objek jenis Account terlalu umum untuk berguna. Itu berarti Account adalah kandidat yang baik untuk kelas abstrak:
// deriv_AbstractClasses.cpp
// compile with: /LD
class Account {
public:
Account( double d ); // Constructor.
virtual double GetBalance(); // Obtain balance.
virtual void PrintBalance() = 0; // Pure virtual function.
private:
double _balance;
};
Satu-satunya perbedaan antara deklarasi ini dan yang sebelumnya adalah yang PrintBalance dideklarasikan dengan penentu murni (= 0).
Pembatasan pada kelas abstrak
Kelas abstrak tidak dapat digunakan untuk:
Variabel atau data anggota (Anda tidak dapat mendeklarasikan variabel jenis kelas abstrak)
Jenis argumen (Anda tidak dapat meneruskan kelas abstrak menurut nilai sebagai parameter fungsi)
Jenis pengembalian fungsi (fungsi tidak dapat mengembalikan kelas abstrak menurut nilai)
Jenis konversi eksplisit (Anda tidak dapat mentransmisikan ke jenis kelas abstrak)
Dalam setiap kasus, Anda dapat menggunakan penunjuk atau referensi ke jenis kelas abstrak sebagai gantinya. Misalnya, fungsi dapat mengambil AbstractBase& atau AbstractBase* sebagai parameter, dan Anda dapat mendeklarasikan penunjuk atau referensi jenis kelas abstrak.
Jika konstruktor untuk kelas abstrak memanggil fungsi virtual murni, baik secara langsung atau tidak langsung, hasilnya tidak terdefinisi. Namun, konstruktor dan destruktor untuk kelas abstrak dapat memanggil fungsi anggota lain.
Fungsi virtual murni yang ditentukan
Fungsi virtual murni dalam kelas abstrak dapat didefinisikan, atau memiliki implementasi. Anda hanya dapat memanggil fungsi tersebut dengan menggunakan sintaksis yang sepenuhnya memenuhi syarat:
abstract-class-name::function-name()
Fungsi virtual murni yang ditentukan sangat membantu ketika Anda merancang hierarki kelas yang kelas dasarnya mencakup destruktor virtual murni. Itu karena destruktor kelas dasar selalu dipanggil selama penghancuran objek. Pertimbangkan contoh berikut:
// deriv_RestrictionsOnUsingAbstractClasses.cpp
// Declare an abstract base class with a pure virtual destructor.
// It's the simplest possible abstract class.
class base
{
public:
base() {}
// To define the virtual destructor outside the class:
virtual ~base() = 0;
// Microsoft-specific extension to define it inline:
// virtual ~base() = 0 {};
};
base::~base() {} // required if not using Microsoft extension
class derived : public base
{
public:
derived() {}
~derived() {}
};
int main()
{
derived aDerived; // destructor called when it goes out of scope
}
Contoh menunjukkan bagaimana ekstensi kompilator Microsoft memungkinkan Anda menambahkan definisi sebaris ke virtual murni ~base(). Anda juga dapat menentukannya di luar kelas dengan menggunakan base::~base() {}.
Ketika objek aDerived keluar dari cakupan, destruktor untuk kelas derived dipanggil. Pengkompilasi menghasilkan kode untuk secara implisit memanggil destruktor untuk kelas base setelah derived destruktor. Implementasi kosong untuk fungsi ~base virtual murni memastikan bahwa setidaknya beberapa implementasi ada untuk fungsi tersebut. Tanpa itu, linker menghasilkan kesalahan simbol eksternal yang tidak terselesaikan untuk panggilan implisit.
Catatan
Dalam contoh sebelumnya, fungsi base::~base virtual murni disebut secara implisit dari derived::~derived. Dimungkinkan juga untuk memanggil fungsi virtual murni secara eksplisit dengan menggunakan nama fungsi anggota yang sepenuhnya memenuhi syarat. Fungsi tersebut harus memiliki implementasi, atau panggilan menghasilkan kesalahan pada waktu tautan.