-->

Pemrograman #2 - Konstruktor



Konstruktor

Didalam kelas apa yang akan terjadi jika telah diakses fungsi member padahal sebelumnya belum memiliki nilai yang akan diset? dan apa yang akan terjadi jika salah satu data member yang ada diakses padahal belum pernah diberikan nilai awal?

Untuk menghindari itu, kelas mempunyai fungsi khusus yang disebut konstruktor, dimana secara otomatis dijalankan (called) setiap kali objek dari kelas tersebut dibuat. Didalam konstruktor inilah nanti kelas memungkinkan untuk melakukan inisialisasi terhadap data membernya atau mengalokasikan penyimpanan.

Fungsi konstruktor dinyatakan sama seperti halnya fungsi member. tetapi konstruktor dinyatakan dengan nama yang sama persis seperti nama kelasnya, tanpa tipe kembalian, dan tanpa kata kunci void.

Berikut adalah cara pendeklarasian konstruktor dalam kelas
class Student {
  private:
    string sId;
    string name;
    string gender;
  public:
    Student() {} // Constructor yang didefinisikan didalam class 
    string getName() {return name;}
    void setName(string cName) {name = cName;}
};

Pada potongan diatas konstruktor dideklarasikan dan sekaligus didefinisikan didalam kelas itu sendiri. Dalam pendefinisiannya konstruktor mempunyai dua cara yaitu diluar kelas atau bisa juga dilakukan langsung dari dalam kelas itu sendiri. jika didefinisikan dari luar maka harus menggunakan simbol scope operator (::). Simbol scope operator menunjukan secara detail kepemilikan data member dari sebuah kelas yang sebelumnya telah dideklarasikan.

Berikut cara pendefinisian konstruktor baik didalam maupun diluar kelas.
class Student {
  private:
    string sId;
    string name;
    string gender;
  public:
    Student();  // Constructor
    string getName() {return name;}
    void setName(string cName) {name = cName;}
};

// Constructor yang didefinisikan diluar class
Student::Student() { // Simbol :: menunjukan kepemilikan class
  // do Nothing
}

Overloading Konstruktor dalam Kelas

Ketika konstruktor dideklarasikan dalam sebuah kelas, tidak menutup kemungkinan terjadinya kasus overloading. Didalam bahasa C++, diperbolehkan terdapat dua buah fungsi dengan nama yang sama. Asalkan fungsi tersebut memiliki parameter yang berbeda, baik dari segi jumlah parameter, maupun parameter yang berbeda tipe. Hal itulah yang dinamakan overloading.

Sama halnya kebanyakan fungsi yang ada, konstruktor pada sebuah kelas juga bisa melakukan proses overloading. saratnya juga sama seperti overloading pada fungsi, yaitu memiliki parameter yang berbeda baik jumlah, maupun tipenya.

Dalam pendefinisiannya overloading pada konstruktor juga bisa dilakukan baik didalam kelas maupun diluar kelas. jika diluar kelas maka harus menggunakan tanda scope operator (::). pada contoh berikut akan diperlihatkan bagaimana overloading pada konstruktor dapat didefinisikan langsung didalam kelas.
class Student {
  private:
    string sId;
    string name;
    string gender;
  public:
    Student() {} // Constructor yang didefinisikan didalam class 
    Student(string cSId, string cName, string cGender): 
      sId{ cSId }, 
       name{cName},
      gender {cGender} {}
    string getName() {return name;}
    void setName(string cName) {name = cName;}
};

Dari contoh diatas dapat dilihat terdapat overloading dalam konstruktor, hanya saja pada konstruktor yang kedua memiliki tiga buah parameter yang sama persis seperti tiga buah data member yang ada pada kelas “Student”.

Konstruktor yang kedua dibuat bertujuan untuk memberikan nilai awal terhadap data member secara langsung ketika kelas dibangkitkan (called). Pada saat konstruktor dibangkitkan maka nilai yang ada pada parameter-parameter akan langsung diisikan kedalam masing-masing data member.

Apabila menginginkan pendefinisian konstruktor dari luar kelas maka penulisan kode akan dicontohkan seperti berikut :
class Student {
  private:
    string sId;
    string name;
    string gender;
  public:
    Student();  // Constructor
    // Overloading Constructor
    Student(string cSId, string cName, string cGender);
};

// Constructor yang didefinisikan diluar class
Student::Student() { // Simbol :: menunjukan kepemilikan class
  // do Nothing
}

Student::Student(string cSId, string cName, string cGender) {    sId = cSId;
  name = cName;
  gender = cGender;

}

Destruktor

Destruktor memiliki fungsi yang berlawanan dari konstruktor. Destruktor bertanggung jawab untuk melakukam pembersihan yang diperlukan ketika daur hidup dari kelas berakhir. setiap kelas yang didefinisikan dan dan telah digunakan maka harus dilakukan pembersihan terhadap memori dinamis yang telah digunakan.

Destruktor mempunyai fungsi yang sangat serupa dengan konstruktor yaitu menggunakan nama kelas sebagai namanya sendiri, tidak membutuhkan argument, tipe kembalian, bahkan tidak memerlukan kata kunci void. perbedaan yang jelas antara destruktor dan konstruktor, penulisan destruktor harus diawali dengan tanda tilde (~).
class Student {
  private:
    string sId;
    string name;
    string gender;
  public:
    Student() {} // Constructor yang didefinisikan didalam class 
    ~Student() {} // Destructor yang didefinisikan didalam class
};

Salinan Konstruktor (Copy Constructor)

Copy Constructor adalah konstruktor yang khusus didalam bahasa pemrogramman C++ untuk membuat objek baru sebagai salinan objek yang sudah ada. Argumen pertama menjadi konstruktor yang mereferensikan kepada objek lainnya dari jenis yang sama yang sudah dibangun, dimana memungkinkan diikuti oleh parameter dari jenis apapun.

Umumnya kompilator secara otomatis membuat salonan konstruktor pada setiap kelas. (dikenal dengan salinan implisit konstruktor). Akan tetapi untuk beberapa kasus khusus programmer akan menciptakan salinan konstruktor yang dikenal dengan nama user-defined copy constructor. Dalam kasus tersebut, kompilator tidak hanya membuat satu salinan. Sehingga selalu ada satu salinan konstruktor yang bisa didefinisikan oleh pengguna ataupun oleh sistem.

Berikut kasus-kasus yang dapat mengakibatkan panggilan terhadap salinan konstruktor:
  • Ketika sebuah objek dikembalikan oleh nilai (value)
  • Ketika sebuah objek dilewatkan (ke fungsi) oleh nilai sebagai argument
  • Ketika sebuah objek dilemparkan (thrown)
  • Ketika sebuah objek tertangkap (caught)
  • Ketika sebuah objek diletakan didalam daftar brace-enclosed initialize

Salinan konstruktor dipanggil ketika objek melewati nilai, dikembalikan oleh nilai, atau disalin secara eksplisit. Jika tidak ditemukan salinan konstruktor, maka sistem pada C++ akan menbuat salinan konstruktor default yang membuat salinan secara simple (shallow copy). Jika objek tidak terdapat pointer menuju memori yang dialokasikan secara dinamis, maka shallow copy akan dilakukan

Salinan konstruktor hanya digunakan untuk inisialisasi, dan tidak berlaku untuk tugas-tugas yang mana operator penetapan digunakan sebagai pengganti. Dengan menggunakan user-defined copy constructor maka seorang programmer dapat mendefinisikan perilaku yang harus dilakukan ketika objek itu disalin.

Berikut contoh sederhana dari salinan konstruktor:
/* Berkas CopyConstructor.cpp */
#include <iostream>
using namespace std;

class Student {
  private:
    int absence;
  public : 
    Student() {}  // Default Constructor
    // Simple  Constructor
    Student(int cAbsence): absence{cAbsence} {}
    Student(const Student &obj) { // Copy Constructor
      absence = obj.absence;
    }
    void printOutput() {  
      cout << "The absence is " << absence << endl;
    }
    ~Student() {}
};

int main() {
  Student student1(10);
  //  Ini juga memanggil copy constructor
  Student student2 = student1; 

  student2.printOutput();
  return 0;
}

Salinan konstruktor secara default ini mungkin sesuai dengan kebutuhan banyak kelas. Tetapi Shallow copy hanya menyalin member dari kelas sendiri, dan hal ini mungkin tidak seperti yang diharapkan untuk kelas, karena ini berisikan pointer yang menangani penyimpanan. Untuk tersebut, Shallow copy berarti bahwa nilai pointer disalin, tapi tidak dengan konten itu sendiri. Ini berarti kedua objek (salinan dan yang asli) akan berbagi sebuah objek string tunggal (objek itu keduanya akan menunjuk ke objek yang sama), dan di beberapa titik (pada destruktor) kedua objek akan mencoba untuk menghapus blok yang sama dari memori, mungkin menyebabkan program untuk crash pada saat runtime. Ini dapat diselesaikan dengan mendefinisikan salinan konstruktor yang melakukan deep copy.

Deep copy yang dilakukan oleh salinan konstruktor ini mengalokasikan penyimpanan untuk string yang baru, yang diinisialisasi agar berisikan salinan dari objek yang asli. Dengan cara ini kedua objek akan memiliki perbedaan salinan dari konten yang tersimpan di lokasi yang berbeda.

Berikut contoh dari deep copy:
/* Berkas CopyConstructor2.cpp */
#include <iostream>
using namespace std;

class Student {
  private:
    string *name;
  public: 
    Student() {}  // Default Constructor
    Student (const string &cName) : name(new string(cName)) {}
    // Copy Constructor
    Student (const Student &obj) : 
      name(new string(obj.showContent())) {}
    // Akses konten
    const string &showContent() const {return *name;}
    ~Student () {delete name;}
};

int main () {
  Student student("Fai Filza");
  Student copy = student;

  cout << "Copy Content : " << copy.showContent();
  return 0;
}


Static Member

Static adalah sebuah kata kunci pada bahasa C++ yang digunakan untuk memberikan karakteristik khusus untuk sebuah elemen. Elemen static dialokasikan penyimpanannya hanya sekali selama program dijalankan (program lifetime) didalam area penyimpanan static. Dan static mempunyai lingkup sampai daur hidup program berhenti. Sebuah kelas dapat berisikan static pada member-membernya baik didata maupun difungsi.

Static data member dari sebuah kelas juga dikenal sebagai “Class Variable”, karena hanya ada satu variabel umum untuk semua objek-objek yang ada dari kelas yang sama. berbagi nilai yang sama, dan nilai tersebut tidak berbeda antara satu objek dengan objek yang lain.

Static dapat didefinisikan dengan menggunakan kata kunci static. Ketika mendeklarasikan member dari sebuah kelas sebagai static, itu berarti tidak peduli berapa banyak objek kelas yang diciptakan, hanya ada satu static member yang tersalin. Sebuah static member dibagikan oleh semua objek kelas. Semua static data diinisialisasikan ke nol ketika ojek pertama dibuat jika tidak ada inisialisasi lainnya yang muncul.

Berikut contoh sederhana membuat sebuah sebuah static member pada kelas:
/* Berkas StaticMember.cpp */
#include <iostream>
using namespace std;

class Student {
  private:
    static int absence;
  public : 
    Student() {}
    int getAbsence() {return absence;}
    void setAbsence(int cAbsence) {
      absence = (absence > 0) ? absence + cAbsence : cAbsence;
    }
    void printOutput() {  
      cout << "The absence is " << absence << endl;
    }
    ~Student() {}
};

int Student::absence = 1; // Deklarasi static data member harus diluar dari kelas

int main() {
  Student obj1;
  obj1.setAbsence(1);

  Student obj2;
  obj2.setAbsence(3);

  Student obj3;
  obj3.setAbsence(1);
  cout << "absence now is " << obj3.getAbsence() << endl;
  return 0;
}
Load Comments

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel