Monday, December 26, 2016

Bab 11. Soal & Penyelesaian C++

PEWARISAN LANJUT





Soal & Penyelesaian
1.       Tulislah kode untuk mengimplementasikan kelas String, yang akan dipakai pada soal-soal berikutnya.
Penyelesaian:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//kelasString.h
#include <iostream>
#include <string.h>
using namespace std;

class String
{
public:
    // konstruktor
    String();
    String(const char *const);
    String(const String &);
    ~String();

    // operator-operator teroverload
    char & operator[](int offset);
    char operator[](int offset) const;
    String operator+(const String&);
    void operator+=(const String&);
    String & operator= (const String &);

    // aksesor
    int GetPjg()const { return pjgNya; }
    const char * GetString() const { return stringNya; }
    // static int HitungKonstruktor;

private:
    String (int); // konstruktor private
    char * stringNya;
    unsigned short pjgNya;

};

// konstruktor default yang menciptakan string 0 byte
String::String()
{
    stringNya = new char[1];
    stringNya[0] = '\0';
    pjgNya=0;
    // cout << "\tKonstruktor string default\n";
    // HitungKonstruktor++;
}

// konstruktor private (penolong), digunakan hanya oleh
// metode-metode kelas untuk menciptakan sebuah string baru
// dengan ukuran yang diminta, yang diisi dengan Null.
String::String(int pjg)
{
    stringNya = new char[pjg+1];
    for (int i = 0; i<=pjg; i++)
        stringNya[i] = '\0';
    pjgNya=pjg;
    // cout << "\tKonstruktor String(int)\n";
    // HitungKonstruktor++;
}

// Mengkonversi karakter array menjadi string
String::String(const char * const cString)
{
    pjgNya = strlen(cString);
    stringNya = new char[pjgNya+1];
    for (int i = 0; i<pjgNya; i++)
        stringNya[i] = cString[i];
    stringNya[pjgNya]='\0';
    // cout << "\tKonstruktor String(char*)\n";
    // HitungKonstruktor++;
}

// konstruktor penyalin
String::String (const String & rhs)
{
    pjgNya=rhs.GetPjg();
    stringNya = new char[pjgNya+1];
    for (int i = 0; i<pjgNya;i++)
        stringNya[i] = rhs[i];
    stringNya[pjgNya] = '\0';
    // cout << "\tKonstruktor String(String&)\n";
    // HitungKonstruktor++;
}

// destruktor, membebaskan memori yang terpakai
String::~String ()
{
    delete [] stringNya;
    pjgNya = 0;
    // cout << "\tDestruktor String\n";
}

// operator sama dengan, membebaskan memori yang dipakai
// kemudian menyalin string dan ukurannya
String& String::operator=(const String & rhs)
{
    if (this == &rhs)
        return *this;
    delete [] stringNya;
    pjgNya=rhs.GetPjg();
    stringNya = new char[pjgNya+1];

    for (int i = 0; i<pjgNya;i++)
        stringNya[i] = rhs[i];
    stringNya[pjgNya] = '\0';
    return *this;
    // cout << "\tOperator=\n";
}

// operator offset konstan, menghasilkan
// referensi ke karakter sehingga ia dapat
// diubah!
char & String::operator[](int offset)
{
    if (offset > pjgNya)
        return stringNya[pjgNya-1];
    else
        return stringNya[offset];
}

// offset konstan yang digunakan pada
// objek konstan
char String::operator[](int offset) const
{
    if (offset > pjgNya)
        return stringNya[pjgNya-1];
    else
        return stringNya[offset];
}

// menciptakan sebuah string baru dengan menambahkan
// string sekarang kepada rhs
String String::operator+(const String& rhs)
{
    int pjgTotal = pjgNya + rhs.GetPjg();
    String temp(pjgTotal);
    int i, j;

    for (i = 0; i<pjgNya; i++)
        temp[i] = stringNya[i];
    for (j = 0; j<rhs.GetPjg(); j++, i++)
        temp[i] = rhs[j];
 
    temp[pjgTotal]='\0';
    return temp;
}

// mengubah string sekarang, tidak menghasilkan apapun
void String::operator+=(const String& rhs)
{
    unsigned short pjgRhs = rhs.GetPjg();
    unsigned short pjgTotal = pjgNya + pjgRhs;
    String temp(pjgTotal);
    int i, j;

    for (i = 0; i<pjgNya; i++)
        temp[i] = stringNya[i];
    for (j = 0; j<rhs.GetPjg(); j++, i++)
        temp[i] = rhs[i-pjgNya];

    temp[pjgTotal]='\0';
    *this = temp;
}

2.       Tulislah sebuah program C++ untuk mengimplementasikan kelas Karyawan yang memuat tiga objek string. Ketiga objek tersebut dipakai untuk memuat nama depan, nama belakang, dan alamat dari seorang karyawan.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//kelasKaryawan.cpp
#include "kelasString.h"
#include <conio.h>

class Karyawan
{
public:
    Karyawan();
    Karyawan(char *, char *, char *, long);
    ~Karyawan();
    Karyawan(const Karyawan&);
    Karyawan & operator= (const Karyawan &);

    const String & GetNamaDepan() const
    { return namaDepanNya; }
    const String & GetNamaBelakang() const { return namaBelakangNya; }
    const String & GetAlamat() const { return alamatNya; }
    long GetGaji() const { return gajiNya; }

    void SetNamaDepan(const String & namaD)
    { namaDepanNya = namaD; }

    void SetNamaBelakang(const String & namaB)
    { namaBelakangNya = namaB; }

    void SetAlamat(const String & alamat)
    { alamatNya = alamat; }

    void SetGaji(long gaji) { gajiNya = gaji; }

private:
    String namaDepanNya;
    String namaBelakangNya;
    String alamatNya;
    long gajiNya;
};

Karyawan::Karyawan():
    namaDepanNya(""),
    namaBelakangNya(""),
    alamatNya(""),
    gajiNya(0)
    {}

Karyawan::Karyawan(char * namaDepan, char * namaBelakang,
char * alamat, long gaji):
namaDepanNya(namaDepan),
namaBelakangNya(namaBelakang),
alamatNya(alamat),
gajiNya(gaji)
{}

Karyawan::Karyawan(const Karyawan & rhs):
namaDepanNya(rhs.GetNamaDepan()),
namaBelakangNya(rhs.GetNamaBelakang()),
alamatNya(rhs.GetAlamat()),
gajiNya(rhs.GetGaji())
{}

Karyawan::~Karyawan() {}

Karyawan & Karyawan::operator= (const Karyawan & rhs)
{
    if (this == &rhs)
        return *this;

    namaDepanNya = rhs.GetNamaDepan();
    namaBelakangNya = rhs.GetNamaBelakang();
    alamatNya = rhs.GetAlamat();
    gajiNya = rhs.GetGaji();

    return *this;
}

int main()
{
    Karyawan Robert("Tohonan","Sianipar","Jl Medan Pematang Siantar", 7000000);
    Robert.SetGaji(15000000);
    String namaBelakang("Siahaan");
    Robert.SetNamaBelakang(namaBelakang);
    Robert.SetNamaDepan("Rico");

    cout << "Nama: ";
    cout << Robert.GetNamaDepan().GetString();
    cout << " " << Robert.GetNamaBelakang().GetString();
    cout << ".\nAlamat: ";
    cout << Robert.GetAlamat().GetString();
    cout << ".\nGaji: " ;
    cout << Robert.GetGaji();

    getch();
    return 0;
}

Nama: Rico Siahaan.
Alamat: Jl Medan Pematang Siantar.
Gaji: 15000000

3.       Perbaikilah program pada soal nomor 2 sehingga Anda dapat mengetahui objek-objek yang sedang diciptakan.
Penyelesaian:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//kelasString.h
#include <iostream>
#include <string.h>
using namespace std;

class String
{
public:
    // konstruktor
    String();
    String(const char *const);
    String(const String &);
    ~String();

    // operator-operator teroverload
    char & operator[](int offset);
    char operator[](int offset) const;
    String operator+(const String&);
    void operator+=(const String&);
    String & operator= (const String &);

    // aksesor
    int GetPjg()const { return pjgNya; }
    const char * GetString() const { return stringNya; }
    // static int HitungKonstruktor;

private:
    String (int); // konstruktor private
    char * stringNya;
    unsigned short pjgNya;

};

// konstruktor default yang menciptakan string 0 byte
String::String()
{
    stringNya = new char[1];
    stringNya[0] = '\0';
    pjgNya=0;
    cout << "\tKonstruktor string default\n";
    // HitungKonstruktor++;
}

// konstruktor private (penolong), digunakan hanya oleh
// metode-metode kelas untuk menciptakan sebuah string baru
// dengan ukuran yang diminta, yang diisi dengan Null.
String::String(int pjg)
{
    stringNya = new char[pjg+1];
    for (int i = 0; i<=pjg; i++)
        stringNya[i] = '\0';
    pjgNya=pjg;
    cout << "\tKonstruktor String(int)\n";
    // HitungKonstruktor++;
}

// Mengkonversi karakter array menjadi string
String::String(const char * const cString)
{
    pjgNya = strlen(cString);
    stringNya = new char[pjgNya+1];
    for (int i = 0; i<pjgNya; i++)
        stringNya[i] = cString[i];
    stringNya[pjgNya]='\0';
    cout << "\tKonstruktor String(char*)\n";
    // HitungKonstruktor++;
}

// konstruktor penyalin
String::String (const String & rhs)
{
    pjgNya=rhs.GetPjg();
    stringNya = new char[pjgNya+1];
    for (int i = 0; i<pjgNya;i++)
        stringNya[i] = rhs[i];
    stringNya[pjgNya] = '\0';
    cout << "\tKonstruktor String(String&)\n";
    // HitungKonstruktor++;
}

// destruktor, membebaskan memori yang terpakai
String::~String ()
{
    delete [] stringNya;
    pjgNya = 0;
    cout << "\tDestruktor String\n";
}

// operator sama dengan, membebaskan memori yang dipakai
// kemudian menyalin string dan ukurannya
String& String::operator=(const String & rhs)
{
    if (this == &rhs)
        return *this;
    delete [] stringNya;
    pjgNya=rhs.GetPjg();
    stringNya = new char[pjgNya+1];

    for (int i = 0; i<pjgNya;i++)
        stringNya[i] = rhs[i];
    stringNya[pjgNya] = '\0';
    return *this;
    cout << "\tOperator=\n";
}

// operator offset konstan, menghasilkan
// referensi ke karakter sehingga ia dapat
// diubah!
char & String::operator[](int offset)
{
    if (offset > pjgNya)
        return stringNya[pjgNya-1];
    else
        return stringNya[offset];
}

// offset konstan yang digunakan pada
// objek konstan
char String::operator[](int offset) const
{
    if (offset > pjgNya)
        return stringNya[pjgNya-1];
    else
        return stringNya[offset];
}

// menciptakan sebuah string baru dengan menambahkan
// string sekarang kepada rhs
String String::operator+(const String& rhs)
{
    int pjgTotal = pjgNya + rhs.GetPjg();
    String temp(pjgTotal);
    int i, j;

    for (i = 0; i<pjgNya; i++)
        temp[i] = stringNya[i];
    for (j = 0; j<rhs.GetPjg(); j++, i++)
        temp[i] = rhs[j];
 
    temp[pjgTotal]='\0';
    return temp;
}

// mengubah string sekarang, tidak menghasilkan apapun
void String::operator+=(const String& rhs)
{
    unsigned short pjgRhs = rhs.GetPjg();
    unsigned short pjgTotal = pjgNya + pjgRhs;
    String temp(pjgTotal);
    int i, j;

    for (i = 0; i<pjgNya; i++)
        temp[i] = stringNya[i];
    for (j = 0; j<rhs.GetPjg(); j++, i++)
        temp[i] = rhs[i-pjgNya];

    temp[pjgTotal]='\0';
    *this = temp;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//kelasKaryawanTerperbaiki.cpp
#include "kelasString.h"
#include <conio.h>

class Karyawan
{
public:
    Karyawan();
    Karyawan(char *, char *, char *, long);
    ~Karyawan();
    Karyawan(const Karyawan&);
    Karyawan & operator= (const Karyawan &);

    const String & GetNamaDepan() const
    { return namaDepanNya; }
    const String & GetNamaBelakang() const { return namaBelakangNya; }
    const String & GetAlamat() const { return alamatNya; }
    long GetGaji() const { return gajiNya; }

    void SetNamaDepan(const String & namaD)
    { namaDepanNya = namaD; }

    void SetNamaBelakang(const String & namaB)
    { namaBelakangNya = namaB; }

    void SetAlamat(const String & alamat)
    { alamatNya = alamat; }

    void SetGaji(long gaji) { gajiNya = gaji; }

private:
    String namaDepanNya;
    String namaBelakangNya;
    String alamatNya;
    long gajiNya;
};

Karyawan::Karyawan():
    namaDepanNya(""),
    namaBelakangNya(""),
    alamatNya(""),
    gajiNya(0)
    {}

Karyawan::Karyawan(char * namaDepan, char * namaBelakang,
char * alamat, long gaji):
namaDepanNya(namaDepan),
namaBelakangNya(namaBelakang),
alamatNya(alamat),
gajiNya(gaji)
{}

Karyawan::Karyawan(const Karyawan & rhs):
namaDepanNya(rhs.GetNamaDepan()),
namaBelakangNya(rhs.GetNamaBelakang()),
alamatNya(rhs.GetAlamat()),
gajiNya(rhs.GetGaji())
{}

Karyawan::~Karyawan() {}

Karyawan & Karyawan::operator= (const Karyawan & rhs)
{
    if (this == &rhs)
        return *this;

    namaDepanNya = rhs.GetNamaDepan();
    namaBelakangNya = rhs.GetNamaBelakang();
    alamatNya = rhs.GetAlamat();
    gajiNya = rhs.GetGaji();

    return *this;
}

int main()
{
    Karyawan Robert("Tohonan","Sianipar","Jl Medan Pematang Siantar", 7000000);
    Robert.SetGaji(15000000);
    String namaBelakang("Siahaan");
    Robert.SetNamaBelakang(namaBelakang);
    Robert.SetNamaDepan("Rico");

    cout << "Nama: ";
    cout << Robert.GetNamaDepan().GetString();
    cout << " " << Robert.GetNamaBelakang().GetString();
    cout << ".\nAlamat: ";
    cout << Robert.GetAlamat().GetString();
    cout << ".\nGaji: " ;
    cout << Robert.GetGaji();

    getch();
    return 0;
}

        Konstruktor String(char*)
        Konstruktor String(char*)
        Konstruktor String(char*)
        Konstruktor String(char*)
        Konstruktor String(char*)
        Destruktor String
Nama: Rico Siahaan.
Alamat: Jl Medan Pematang Siantar.
Gaji: 15000000

4.       Tulislah sebuah program yang memanggil fungsi-fungsi penampil, yang melewatkan objek Karyawan, pertama-tama dengan referensi dan kemudian dengan nilai.
Penyelesaian:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// KaryawanPelewatan.cpp
#include "kelasString.h"
#include <conio.h>

class Karyawan
{
public:
    Karyawan();
    Karyawan(char *, char *, char *, long);
    ~Karyawan();
    Karyawan(const Karyawan&);
    Karyawan & operator= (const Karyawan &);

    const String & GetNamaDepan() const
    { return namaDepanNya; }
    const String & GetNamaBelakang() const { return namaBelakangNya; }
    const String & GetAlamat() const { return alamatNya; }
    long GetGaji() const { return gajiNya; }

    void SetNamaDepan(const String & namaD)
    { namaDepanNya = namaD; }

    void SetNamaBelakang(const String & namaB)
    { namaBelakangNya = namaB; }

    void SetAlamat(const String & alamat)
    { alamatNya = alamat; }

    void SetGaji(long gaji) { gajiNya = gaji; }

private:
    String namaDepanNya;
    String namaBelakangNya;
    String alamatNya;
    long gajiNya;
};

Karyawan::Karyawan():
    namaDepanNya(""),
    namaBelakangNya(""),
    alamatNya(""),
    gajiNya(0)
    {}

Karyawan::Karyawan(char * namaDepan, char * namaBelakang,
char * alamat, long gaji):
namaDepanNya(namaDepan),
namaBelakangNya(namaBelakang),
alamatNya(alamat),
gajiNya(gaji)
{}

Karyawan::Karyawan(const Karyawan & rhs):
namaDepanNya(rhs.GetNamaDepan()),
namaBelakangNya(rhs.GetNamaBelakang()),
alamatNya(rhs.GetAlamat()),
gajiNya(rhs.GetGaji())
{}

Karyawan::~Karyawan() {}

Karyawan & Karyawan::operator= (const Karyawan & rhs)
{
    if (this == &rhs)
        return *this;

    namaDepanNya = rhs.GetNamaDepan();
    namaBelakangNya = rhs.GetNamaBelakang();
    alamatNya = rhs.GetAlamat();
    gajiNya = rhs.GetGaji();

    return *this;
}

void FungsiTampil(Karyawan);
void FungsiTampilRef(const Karyawan&);

int main()
{
    Karyawan Robert("Tohonan","Sianipar","Jl Medan Pematang Siantar", 7000000);
    Robert.SetGaji(15000000);
    String namaBelakang("Siahaan");
    Robert.SetNamaBelakang(namaBelakang);
    Robert.SetNamaDepan("Rico");

    FungsiTampilRef(Robert);

    FungsiTampil(Robert);
      
    getch();
    return 0;
}

void FungsiTampil (Karyawan Robert)
{
    cout << "Nama: ";
    cout << Robert.GetNamaDepan().GetString();
    cout << " " << Robert.GetNamaBelakang().GetString();
    cout << ".\nAlamat: ";
    cout << Robert.GetAlamat().GetString();
    cout << ".\nGaji: " ;
    cout << Robert.GetGaji();
    cout << endl;
}

void FungsiTampilRef (const Karyawan& Robert)
{
    cout << "Nama: ";
    cout << Robert.GetNamaDepan().GetString();
    cout << " " << Robert.GetNamaBelakang().GetString();
    cout << "\nAlamat: ";
    cout << Robert.GetAlamat().GetString();
    cout << "\nGaji: " ;
    cout << Robert.GetGaji();
    cout << endl;
}

        Konstruktor String(char*)
        Konstruktor String(char*)
        Konstruktor String(char*)
        Konstruktor String(char*)
        Konstruktor String(char*)
        Destruktor String
Nama: Rico Siahaan
Alamat: Jl Medan Pematang Siantar
Gaji: 15000000
        Konstruktor String(String&)
        Konstruktor String(String&)
        Konstruktor String(String&)
Nama: Rico Siahaan.
Alamat: Jl Medan Pematang Siantar.
Gaji: 15000000
        Destruktor String
        Destruktor String
        Destruktor String

5.       Agregasi merupakan pendeklarasian sebuah objek sebagai anggota dari kelas lain yang dimuat oleh kelas tersebut. Delegasi merupakan penggunaan anggota dari kelas teragregasi untuk melakukan fungsi-fungsi untuk kelas pemuat. Ilustrasikanlah kedua mekanisme ini pada sebuah program C++.
Penyelesaian:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
250
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
//DelegasiAgregasi.cpp
#include <iostream>
#include <conio.h>
using namespace std;

// **************** Komponen ************

// Kelas basis abstrak untuk komponen
class Komponen
{
public:
    Komponen():nomorKomponenNya(1) {}
    Komponen(int NomorKomponen):
    nomorKomponenNya(NomorKomponen){}
    virtual ~Komponen(){}
   
    int GetNomorKomponen() const
    { return nomorKomponenNya; }

    virtual void Tampil() const =0;

private:
    int nomorKomponenNya;
};

// implementasi dari fungsi virtual murni sehingga
// kelas-kelas terderivasi dapat terantai
void Komponen::Tampil() const
{
    cout << "\nNomor Komponen: " << nomorKomponenNya << endl;
}

// **************** Komponen Mobil ************

class KomponenMobil : public Komponen
{
public:
    KomponenMobil():tahunModelNya(94){}
    KomponenMobil(int tahun, int NomorKomponen);
    virtual void Tampil() const
    {
        Komponen::Tampil();
        cout << "Tahun Model: ";
        cout << tahunModelNya << endl;
    }

private:
    int tahunModelNya;
};

KomponenMobil::KomponenMobil(int tahun, int NomorKomponen):
tahunModelNya(tahun),
Komponen(NomorKomponen)
{}


// **************** Komponen Pesawat ************

class KomponenPesawat : public Komponen
{
public:
    KomponenPesawat():nomorMesinNya(1){};
    KomponenPesawat(int NomorMesin, int NomorKomponen);

    virtual void Tampil() const
    {
        Komponen::Tampil();
        cout << "Nomor Mesin: ";
        cout << nomorMesinNya << endl;
    }

private:
    int nomorMesinNya;
};

KomponenPesawat::KomponenPesawat
(int NomorMesin, int NomorKomponen):
nomorMesinNya(NomorMesin),
Komponen(NomorKomponen)
{}

// **************** Simpul Komponen ************
class SimpulKomponen
{
public:
    SimpulKomponen (Komponen*);
    ~SimpulKomponen();

    void SetBrktnya(SimpulKomponen * simpul)
    { brktNya = simpul; }

    SimpulKomponen * GetBrktnya() const;
    Komponen * GetKomponen() const;

private:
    Komponen *komponenNya;
    SimpulKomponen * brktNya;
};

// Implementasi-implementasi SimpulKomponen ...
SimpulKomponen::SimpulKomponen(Komponen* pKomponen):
komponenNya(pKomponen),
brktNya(0)
{}

SimpulKomponen::~SimpulKomponen()
{
    delete komponenNya;
    komponenNya = 0;
    delete brktNya;
    brktNya = 0;
}

// Menghasilkan NULL jika tidak ada SimpulKomponen berikutnya
SimpulKomponen * SimpulKomponen::GetBrktnya() const
{
    return brktNya;
}

Komponen * SimpulKomponen::GetKomponen() const
{
    if (komponenNya)
        return komponenNya;
    else
        return NULL; //error
}

// **************** Senarai Komponen ************
class SenaraiKomponen
{
public:
    SenaraiKomponen();
    ~SenaraiKomponen();

    // memerlukan konstruktor penyalin dan operator sama dengan!
    void Iterasi(void (Komponen::*f)()const) const;
    Komponen* Cari(int & posisi, int NomorKomponen) const;
    Komponen* GetPertama() const;
    void Sisip(Komponen *);
    Komponen* operator[](int) const;
    int GetHitung() const { return hitungNya; }

    static SenaraiKomponen& GetSenaraiKomponenGlobal()
    {
        return SenaraiKomponenGlobal;
    }

private:
    SimpulKomponen * pKepala;
    int hitungNya;
    static SenaraiKomponen SenaraiKomponenGlobal;
};

SenaraiKomponen SenaraiKomponen::SenaraiKomponenGlobal;


SenaraiKomponen::SenaraiKomponen():
pKepala(0),
hitungNya(0)
{}

SenaraiKomponen::~SenaraiKomponen()
{
    delete pKepala;
}

Komponen* SenaraiKomponen::GetPertama() const
{
    if (pKepala)
        return pKepala->GetKomponen();
    else
        return NULL; // error
}

Komponen * SenaraiKomponen::operator[](int offSet) const
{
    SimpulKomponen* pSimpul = pKepala;

    if (!pKepala)
        return NULL; // error

    if (offSet > hitungNya)
        return NULL; // error

    for (int i=0;i<offSet; i++)
        pSimpul = pSimpul->GetBrktnya();

    return pSimpul->GetKomponen();
}

Komponen* SenaraiKomponen::Cari(
int & posisi,
int NomorKomponen) const
{
    SimpulKomponen * pSimpul = 0;
    for (pSimpul = pKepala, posisi = 0;
        pSimpul!=NULL;
        pSimpul = pSimpul->GetBrktnya(), posisi++)
    {
        if (pSimpul->GetKomponen()->GetNomorKomponen() == NomorKomponen)
            break;
    }

    if (pSimpul == NULL)
        return NULL;
    else
        return pSimpul->GetKomponen();
}

void SenaraiKomponen::Iterasi(void (Komponen::*fungsi)()const) const
{
    if (!pKepala)
        return;
    SimpulKomponen* pSimpul = pKepala;
    do
        (pSimpul->GetKomponen()->*fungsi)();
    while ((pSimpul = pSimpul->GetBrktnya()) != 0);
}

void SenaraiKomponen::Sisip(Komponen* pKomponen)
{
    SimpulKomponen * pSimpul = new SimpulKomponen(pKomponen);
    SimpulKomponen * pSkrg = pKepala;
    SimpulKomponen * pBrktnya = 0;

    int Baru = pKomponen->GetNomorKomponen();
    int Brktnya = 0;
    hitungNya++;

    if (!pKepala)
    {
        pKepala = pSimpul;
        return;
    }

    // jika simpul ini lebih kecil dari kepala
    // simpul ini menjadi kepala baru
    if (pKepala->GetKomponen()->GetNomorKomponen() > Baru)
    {
        pSimpul->SetBrktnya(pKepala);
        pKepala = pSimpul;
        return;
    }

    for (;;)
    {
        // jika tidak ada simpul berikutnya, tempelkan pada simpul baru
        if (!pSkrg->GetBrktnya())
        {
            pSkrg->SetBrktnya(pSimpul);
            return;
        }

        pBrktnya = pSkrg->GetBrktnya();
        Brktnya = pBrktnya->GetKomponen()->GetNomorKomponen();
        if (Brktnya > Baru)
        {
            pSkrg->SetBrktnya(pSimpul);
            pSimpul->SetBrktnya(pBrktnya);
            return;
        }

           pSkrg = pBrktnya;
    }
}

class KatalogKomponen
{
public:
    void Sisip(Komponen *);
    int Ada(int NomorKomponen);
    Komponen * Get(int NomorKomponen);
    int operator+(const KatalogKomponen &);
    void TampilSemua() { senaraiKomponen.Iterasi(&Komponen::Tampil); }

private:
    SenaraiKomponen senaraiKomponen;
};

void KatalogKomponen::Sisip(Komponen * komponenBaru)
{
    int NomorKomponen = komponenBaru->GetNomorKomponen();
    int offset;

    if (!senaraiKomponen.Cari(offset, NomorKomponen))
    {
        senaraiKomponen.Sisip(komponenBaru);
    }
   
    else
    {
        cout << NomorKomponen << " adalah entri ";
        switch (offset)
        {
            case 0: cout << "pertama "; break;
            case 1: cout << "kedua "; break;
            case 2: cout << "ketiga "; break;
            default: cout << "ke-" << offset+1;
        }
        cout << "Tolak!" << endl;
    }
}

int KatalogKomponen::Ada(int NomorKomponen)
{
    int offset;
    senaraiKomponen.Cari(offset,NomorKomponen);
    return offset;
}

Komponen * KatalogKomponen::Get(int NomorKomponen)
{
    int offset;
    Komponen * komponen = senaraiKomponen.Cari(offset, NomorKomponen);
    return komponen;
}

int main()
{
    KatalogKomponen pc;
    Komponen * pKomponen = 0;
    int NomorKomponen;
    int nilai;
    int pilihan = 99;

    while (pilihan != 0)
    {
        cout << "(0)Keluar (1)Mobil (2)Pesawat: ";
        cin >> pilihan;

        if (pilihan != 0)
        {
            cout << "Nomor Komponen Baru?: ";
            cin >> NomorKomponen;

            if (pilihan == 1)
            {
                cout << "Tahun Model?: ";
                cin >> nilai;
                pKomponen = new KomponenMobil(nilai,NomorKomponen);
            }

            else
            {
                cout << "Nomor Mesin?: ";
                cin >> nilai;
                pKomponen = new KomponenPesawat(nilai,NomorKomponen);
            }
            pc.Sisip(pKomponen);
        }
    }
    pc.TampilSemua();

    getch();
    return 0;
}

(0)Keluar (1)Mobil (2)Pesawat: 1
Nomor Komponen Baru?: 1234
Tahun Model?: 1988
(0)Keluar (1)Mobil (2)Pesawat: 1

Nomor Komponen Baru?: 1234
Tahun Model?: 1988
1234 adalah entri pertama Tolak!

(0)Keluar (1)Mobil (2)Pesawat: 1
Nomor Komponen Baru?: 2345
Tahun Model?: 1999

(0)Keluar (1)Mobil (2)Pesawat: 2
Nomor Komponen Baru?: 3456
Nomor Mesin?: 2001

(0)Keluar (1)Mobil (2)Pesawat: 2
Nomor Komponen Baru?: 3456
Nomor Mesin?: 2001
3456 adalah entri ketiga Tolak!

(0)Keluar (1)Mobil (2)Pesawat:

6.       Gunakanlah mekanisme pewarisan private pada kode pada soal nomor 5 tersebut.
Penyelesaian:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
250
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
//pewarisanPrivate.cpp
#include <iostream>
#include <conio.h>
using namespace std;

// **************** Komponen ************

// Kelas basis abstrak untuk komponen
class Komponen
{
public:
    Komponen():nomorKomponenNya(1) {}
    Komponen(int NomorKomponen):
    nomorKomponenNya(NomorKomponen){}
    virtual ~Komponen(){}
   
    int GetNomorKomponen() const
    { return nomorKomponenNya; }

    virtual void Tampil() const =0;

private:
    int nomorKomponenNya;
};

// implementasi dari fungsi virtual murni sehingga
// kelas-kelas terderivasi dapat terantai
void Komponen::Tampil() const
{
    cout << "\nNomor Komponen: " << nomorKomponenNya << endl;
}

// **************** Komponen Mobil ************

class KomponenMobil : public Komponen
{
public:
    KomponenMobil():tahunModelNya(94){}
    KomponenMobil(int tahun, int NomorKomponen);
    virtual void Tampil() const
    {
        Komponen::Tampil();
        cout << "Tahun Model: ";
        cout << tahunModelNya << endl;
    }

private:
    int tahunModelNya;
};

KomponenMobil::KomponenMobil(int tahun, int NomorKomponen):
tahunModelNya(tahun),
Komponen(NomorKomponen)
{}


// **************** Komponen Pesawat ************

class KomponenPesawat : public Komponen
{
public:
    KomponenPesawat():nomorMesinNya(1){};
    KomponenPesawat(int NomorMesin, int NomorKomponen);

    virtual void Tampil() const
    {
        Komponen::Tampil();
        cout << "Nomor Mesin: ";
        cout << nomorMesinNya << endl;
    }

private:
    int nomorMesinNya;
};

KomponenPesawat::KomponenPesawat
(int NomorMesin, int NomorKomponen):
nomorMesinNya(NomorMesin),
Komponen(NomorKomponen)
{}

// **************** Simpul Komponen ************
class SimpulKomponen
{
public:
    SimpulKomponen (Komponen*);
    ~SimpulKomponen();

    void SetBrktnya(SimpulKomponen * simpul)
    { brktNya = simpul; }

    SimpulKomponen * GetBrktnya() const;
    Komponen * GetKomponen() const;

private:
    Komponen *komponenNya;
    SimpulKomponen * brktNya;
};

// Implementasi-implementasi SimpulKomponen ...
SimpulKomponen::SimpulKomponen(Komponen* pKomponen):
komponenNya(pKomponen),
brktNya(0)
{}

SimpulKomponen::~SimpulKomponen()
{
    delete komponenNya;
    komponenNya = 0;
    delete brktNya;
    brktNya = 0;
}

// Menghasilkan NULL jika tidak ada SimpulKomponen berikutnya
SimpulKomponen * SimpulKomponen::GetBrktnya() const
{
    return brktNya;
}

Komponen * SimpulKomponen::GetKomponen() const
{
    if (komponenNya)
        return komponenNya;
    else
        return NULL; //error
}

// **************** Senarai Komponen ************
class SenaraiKomponen
{
public:
    SenaraiKomponen();
    ~SenaraiKomponen();

    // memerlukan konstruktor penyalin dan operator sama dengan!
    void Iterasi(void (Komponen::*f)()const) const;
    Komponen* Cari(int & posisi, int NomorKomponen) const;
    Komponen* GetPertama() const;
    void Sisip(Komponen *);
    Komponen* operator[](int) const;
    int GetHitung() const { return hitungNya; }

    static SenaraiKomponen& GetSenaraiKomponenGlobal()
    {
        return SenaraiKomponenGlobal;
    }

private:
    SimpulKomponen * pKepala;
    int hitungNya;
    static SenaraiKomponen SenaraiKomponenGlobal;
};

SenaraiKomponen SenaraiKomponen::SenaraiKomponenGlobal;


SenaraiKomponen::SenaraiKomponen():
pKepala(0),
hitungNya(0)
{}

SenaraiKomponen::~SenaraiKomponen()
{
    delete pKepala;
}

Komponen* SenaraiKomponen::GetPertama() const
{
    if (pKepala)
        return pKepala->GetKomponen();
    else
        return NULL; // error
}

Komponen * SenaraiKomponen::operator[](int offSet) const
{
    SimpulKomponen* pSimpul = pKepala;

    if (!pKepala)
        return NULL; // error

    if (offSet > hitungNya)
        return NULL; // error

    for (int i=0;i<offSet; i++)
        pSimpul = pSimpul->GetBrktnya();

    return pSimpul->GetKomponen();
}

Komponen* SenaraiKomponen::Cari(
int & posisi,
int NomorKomponen) const
{
    SimpulKomponen * pSimpul = 0;
    for (pSimpul = pKepala, posisi = 0;
        pSimpul!=NULL;
        pSimpul = pSimpul->GetBrktnya(), posisi++)
    {
        if (pSimpul->GetKomponen()->GetNomorKomponen() == NomorKomponen)
            break;
    }

    if (pSimpul == NULL)
        return NULL;
    else
        return pSimpul->GetKomponen();
}

void SenaraiKomponen::Iterasi(void (Komponen::*fungsi)()const) const
{
    if (!pKepala)
        return;
    SimpulKomponen* pSimpul = pKepala;
    do
        (pSimpul->GetKomponen()->*fungsi)();
    while ((pSimpul = pSimpul->GetBrktnya()) != 0);
}

void SenaraiKomponen::Sisip(Komponen* pKomponen)
{
    SimpulKomponen * pSimpul = new SimpulKomponen(pKomponen);
    SimpulKomponen * pSkrg = pKepala;
    SimpulKomponen * pBrktnya = 0;

    int Baru = pKomponen->GetNomorKomponen();
    int Brktnya = 0;
    hitungNya++;

    if (!pKepala)
    {
        pKepala = pSimpul;
        return;
    }

    // jika simpul ini lebih kecil dari kepala
    // simpul ini menjadi kepala baru
    if (pKepala->GetKomponen()->GetNomorKomponen() > Baru)
    {
        pSimpul->SetBrktnya(pKepala);
        pKepala = pSimpul;
        return;
    }

    for (;;)
    {
        // jika tidak ada simpul berikutnya, tempelkan pada simpul baru
        if (!pSkrg->GetBrktnya())
        {
            pSkrg->SetBrktnya(pSimpul);
            return;
        }

        pBrktnya = pSkrg->GetBrktnya();
        Brktnya = pBrktnya->GetKomponen()->GetNomorKomponen();
        if (Brktnya > Baru)
        {
            pSkrg->SetBrktnya(pSimpul);
            pSimpul->SetBrktnya(pBrktnya);
            return;
        }

           pSkrg = pBrktnya;
    }
}

class KatalogKomponen : private SenaraiKomponen
{
public:
    void Sisip(Komponen *);
    int Ada(int NomorKomponen);
    Komponen * Get(int NomorKomponen);
    int operator+(const KatalogKomponen &);
    void TampilSemua() { Iterasi(&Komponen::Tampil); }

private:
};

void KatalogKomponen::Sisip(Komponen * komponenBaru)
{
    int NomorKomponen = komponenBaru->GetNomorKomponen();
    int offset;

    if (!Cari(offset, NomorKomponen))
    {
        Sisip(komponenBaru);
    }
   
    else
    {
        cout << NomorKomponen << " adalah entri ";
        switch (offset)
        {
            case 0: cout << "pertama "; break;
            case 1: cout << "kedua "; break;
            case 2: cout << "ketiga "; break;
            default: cout << "ke-" << offset+1;
        }
        cout << "Tolak!" << endl;
    }
}

int KatalogKomponen::Ada(int NomorKomponen)
{
    int offset;
    Cari(offset,NomorKomponen);
    return offset;
}

Komponen * KatalogKomponen::Get(int NomorKomponen)
{
    int offset;
    return (Cari(offset, NomorKomponen));
}

int main()
{
    KatalogKomponen pc;
    Komponen * pKomponen = 0;
    int NomorKomponen;
    int nilai;
    int pilihan = 99;

    while (pilihan != 0)
    {
        cout << "(0)Keluar (1)Mobil (2)Pesawat: ";
        cin >> pilihan;

        if (pilihan != 0)
        {
            cout << "Nomor Komponen Baru?: ";
            cin >> NomorKomponen;

            if (pilihan == 1)
            {
                cout << "Tahun Model?: ";
                cin >> nilai;
                pKomponen = new KomponenMobil(nilai,NomorKomponen);
            }

            else
            {
                cout << "Nomor Mesin?: ";
                cin >> nilai;
                pKomponen = new KomponenPesawat(nilai,NomorKomponen);
            }
            pc.Sisip(pKomponen);
        }
    }
    pc.TampilSemua();

    getch();
    return 0;
}

(0)Keluar (1)Mobil (2)Pesawat: 1
Nomor Komponen Baru?: 1234
Tahun Model?: 1988
(0)Keluar (1)Mobil (2)Pesawat: 1

Nomor Komponen Baru?: 1234
Tahun Model?: 1988
1234 adalah entri pertama Tolak!

(0)Keluar (1)Mobil (2)Pesawat: 1
Nomor Komponen Baru?: 2345
Tahun Model?: 1999

(0)Keluar (1)Mobil (2)Pesawat: 2
Nomor Komponen Baru?: 3456
Nomor Mesin?: 2001

(0)Keluar (1)Mobil (2)Pesawat: 2
Nomor Komponen Baru?: 3456
Nomor Mesin?: 2001
3456 adalah entri ketiga Tolak!

(0)Keluar (1)Mobil (2)Pesawat:

7.       Jadikanlah kelas SenaraiKomponen sebagai kelas friend dari kelas SimpulKomponen pada kode pada soal nomor 6.
8.          
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
250
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
//pewarisanPrivate.cpp
#include <iostream>
#include <conio.h>
using namespace std;

// **************** Komponen ************

// Kelas basis abstrak untuk komponen
class Komponen
{
public:
    Komponen():nomorKomponenNya(1) {}
    Komponen(int NomorKomponen):
    nomorKomponenNya(NomorKomponen){}
    virtual ~Komponen(){}
   
    int GetNomorKomponen() const
    { return nomorKomponenNya; }

    virtual void Tampil() const =0;

private:
    int nomorKomponenNya;
};

// implementasi dari fungsi virtual murni sehingga
// kelas-kelas terderivasi dapat terantai
void Komponen::Tampil() const
{
    cout << "\nNomor Komponen: " << nomorKomponenNya << endl;
}

// **************** Komponen Mobil ************

class KomponenMobil : public Komponen
{
public:
    KomponenMobil():tahunModelNya(94){}
    KomponenMobil(int tahun, int NomorKomponen);
    virtual void Tampil() const
    {
        Komponen::Tampil();
        cout << "Tahun Model: ";
        cout << tahunModelNya << endl;
    }

private:
    int tahunModelNya;
};

KomponenMobil::KomponenMobil(int tahun, int NomorKomponen):
tahunModelNya(tahun),
Komponen(NomorKomponen)
{}


// **************** Komponen Pesawat ************

class KomponenPesawat : public Komponen
{
public:
    KomponenPesawat():nomorMesinNya(1){};
    KomponenPesawat(int NomorMesin, int NomorKomponen);

    virtual void Tampil() const
    {
        Komponen::Tampil();
        cout << "Nomor Mesin: ";
        cout << nomorMesinNya << endl;
    }

private:
    int nomorMesinNya;
};

KomponenPesawat::KomponenPesawat
(int NomorMesin, int NomorKomponen):
nomorMesinNya(NomorMesin),
Komponen(NomorKomponen)
{}

// **************** Simpul Komponen ************
class SimpulKomponen
{
public:
    friend class SenaraiKomponen;
    SimpulKomponen (Komponen*);
    ~SimpulKomponen();

    void SetBrktnya(SimpulKomponen * simpul)
    { brktNya = simpul; }

    SimpulKomponen * GetBrktnya() const;
    Komponen * GetKomponen() const;

private:
    Komponen *komponenNya;
    SimpulKomponen * brktNya;
};

// Implementasi-implementasi SimpulKomponen ...
SimpulKomponen::SimpulKomponen(Komponen* pKomponen):
komponenNya(pKomponen),
brktNya(0)
{}

SimpulKomponen::~SimpulKomponen()
{
    delete komponenNya;
    komponenNya = 0;
    delete brktNya;
    brktNya = 0;
}

// Menghasilkan NULL jika tidak ada SimpulKomponen berikutnya
SimpulKomponen * SimpulKomponen::GetBrktnya() const
{
    return brktNya;
}

Komponen * SimpulKomponen::GetKomponen() const
{
    if (komponenNya)
        return komponenNya;
    else
        return NULL; //error
}

// **************** Senarai Komponen ************
class SenaraiKomponen
{
public:
    SenaraiKomponen();
    ~SenaraiKomponen();

    // memerlukan konstruktor penyalin dan operator sama dengan!
    void Iterasi(void (Komponen::*f)()const) const;
    Komponen* Cari(int & posisi, int NomorKomponen) const;
    Komponen* GetPertama() const;
    void Sisip(Komponen *);
    Komponen* operator[](int) const;
    int GetHitung() const { return hitungNya; }

    static SenaraiKomponen& GetSenaraiKomponenGlobal()
    {
        return SenaraiKomponenGlobal;
    }

private:
    SimpulKomponen * pKepala;
    int hitungNya;
    static SenaraiKomponen SenaraiKomponenGlobal;
};

SenaraiKomponen SenaraiKomponen::SenaraiKomponenGlobal;


SenaraiKomponen::SenaraiKomponen():
pKepala(0),
hitungNya(0)
{}

SenaraiKomponen::~SenaraiKomponen()
{
    delete pKepala;
}

Komponen* SenaraiKomponen::GetPertama() const
{
    if (pKepala)
        return pKepala->komponenNya;
    else
        return NULL; // error
}

Komponen * SenaraiKomponen::operator[](int offSet) const
{
    SimpulKomponen* pSimpul = pKepala;

    if (!pKepala)
        return NULL; // error

    if (offSet > hitungNya)
        return NULL; // error

    for (int i=0;i<offSet; i++)
        pSimpul = pSimpul->GetBrktnya();

    return pSimpul->GetKomponen();
}

Komponen* SenaraiKomponen::Cari(
int & posisi,
int NomorKomponen) const
{
    SimpulKomponen * pSimpul = 0;
    for (pSimpul = pKepala, posisi = 0;
        pSimpul!=NULL;
        pSimpul = pSimpul->GetBrktnya(), posisi++)
    {
        if (pSimpul->GetKomponen()->GetNomorKomponen() == NomorKomponen)
            break;
    }

    if (pSimpul == NULL)
        return NULL;
    else
        return pSimpul->GetKomponen();
}

void SenaraiKomponen::Iterasi(void (Komponen::*fungsi)()const) const
{
    if (!pKepala)
        return;
    SimpulKomponen* pSimpul = pKepala;
    do
        (pSimpul->GetKomponen()->*fungsi)();
    while ((pSimpul = pSimpul->GetBrktnya()) != 0);
}

void SenaraiKomponen::Sisip(Komponen* pKomponen)
{
    SimpulKomponen * pSimpul = new SimpulKomponen(pKomponen);
    SimpulKomponen * pSkrg = pKepala;
    SimpulKomponen * pBrktnya = 0;

    int Baru = pKomponen->GetNomorKomponen();
    int Brktnya = 0;
    hitungNya++;

    if (!pKepala)
    {
        pKepala = pSimpul;
        return;
    }

    // jika simpul ini lebih kecil dari kepala
    // simpul ini menjadi kepala baru
    if (pKepala->GetKomponen()->GetNomorKomponen() > Baru)
    {
        pSimpul->SetBrktnya(pKepala);
        pKepala = pSimpul;
        return;
    }

    for (;;)
    {
        // jika tidak ada simpul berikutnya, tempelkan pada simpul baru
        if (!pSkrg->GetBrktnya())
        {
            pSkrg->SetBrktnya(pSimpul);
            return;
        }

        pBrktnya = pSkrg->GetBrktnya();
        Brktnya = pBrktnya->GetKomponen()->GetNomorKomponen();
        if (Brktnya > Baru)
        {
            pSkrg->SetBrktnya(pSimpul);
            pSimpul->SetBrktnya(pBrktnya);
            return;
        }

           pSkrg = pBrktnya;
    }
}

class KatalogKomponen : private SenaraiKomponen
{
public:
    void Sisip(Komponen *);
    int Ada(int NomorKomponen);
    Komponen * Get(int NomorKomponen);
    int operator+(const KatalogKomponen &);
    void TampilSemua() { Iterasi(&Komponen::Tampil); }

private:
};

void KatalogKomponen::Sisip(Komponen * komponenBaru)
{
    int NomorKomponen = komponenBaru->GetNomorKomponen();
    int offset;

    if (!Cari(offset, NomorKomponen))
    {
        Sisip(komponenBaru);
    }
   
    else
    {
        cout << NomorKomponen << " adalah entri ";
        switch (offset)
        {
            case 0: cout << "pertama "; break;
            case 1: cout << "kedua "; break;
            case 2: cout << "ketiga "; break;
            default: cout << "ke-" << offset+1;
        }
        cout << "Tolak!" << endl;
    }
}

int KatalogKomponen::Ada(int NomorKomponen)
{
    int offset;
    Cari(offset,NomorKomponen);
    return offset;
}

Komponen * KatalogKomponen::Get(int NomorKomponen)
{
    int offset;
    return (Cari(offset, NomorKomponen));
}

int main()
{
    KatalogKomponen pc;
    Komponen * pKomponen = 0;
    int NomorKomponen;
    int nilai;
    int pilihan = 99;

    while (pilihan != 0)
    {
        cout << "(0)Keluar (1)Mobil (2)Pesawat: ";
        cin >> pilihan;

        if (pilihan != 0)
        {
            cout << "Nomor Komponen Baru?: ";
            cin >> NomorKomponen;

            if (pilihan == 1)
            {
                cout << "Tahun Model?: ";
                cin >> nilai;
                pKomponen = new KomponenMobil(nilai,NomorKomponen);
            }

            else
            {
                cout << "Nomor Mesin?: ";
                cin >> nilai;
                pKomponen = new KomponenPesawat(nilai,NomorKomponen);
            }
            pc.Sisip(pKomponen);
        }
    }
    pc.TampilSemua();

    getch();
    return 0;
}

(0)Keluar (1)Mobil (2)Pesawat: 1
Nomor Komponen Baru?: 1234
Tahun Model?: 1988
(0)Keluar (1)Mobil (2)Pesawat: 1

Nomor Komponen Baru?: 1234
Tahun Model?: 1988
1234 adalah entri pertama Tolak!

(0)Keluar (1)Mobil (2)Pesawat: 1
Nomor Komponen Baru?: 2345
Tahun Model?: 1999

(0)Keluar (1)Mobil (2)Pesawat: 2
Nomor Komponen Baru?: 3456
Nomor Mesin?: 2001

(0)Keluar (1)Mobil (2)Pesawat: 2
Nomor Komponen Baru?: 3456
Nomor Mesin?: 2001
3456 adalah entri ketiga Tolak!

(0)Keluar (1)Mobil (2)Pesawat:




No comments:

Post a Comment