Tempatkan diri Anda pada posisi kompiler: ketika Anda meneruskan mendeklarasikan suatu tipe, yang diketahui kompiler adalah bahwa tipe ini ada; ia tidak tahu apa-apa tentang ukuran, anggota, atau metode. Inilah sebabnya mengapa ini disebut tipe tidak lengkap . Oleh karena itu, Anda tidak dapat menggunakan tipe untuk mendeklarasikan anggota, atau kelas dasar, karena kompiler perlu mengetahui tata letak tipe tersebut.
Dengan asumsi deklarasi maju berikut.
class X;
Inilah yang bisa dan tidak bisa Anda lakukan.
Apa yang dapat Anda lakukan dengan jenis yang tidak lengkap:
Nyatakan anggota sebagai penunjuk atau referensi ke tipe tidak lengkap:
class Foo {
X *p;
X &r;
};
Menyatakan fungsi atau metode yang menerima / mengembalikan tipe tidak lengkap:
void f1(X);
X f2();
Tetapkan fungsi atau metode yang menerima / mengembalikan pointer / referensi ke tipe tidak lengkap (tetapi tanpa menggunakan anggotanya):
void f3(X*, X&) {}
X& f4() {}
X* f5() {}
Apa yang tidak dapat Anda lakukan dengan jenis yang tidak lengkap:
Gunakan itu sebagai kelas dasar
class Foo : X {} // compiler error!
Gunakan itu untuk mendeklarasikan anggota:
class Foo {
X m; // compiler error!
};
Tentukan fungsi atau metode menggunakan tipe ini
void f1(X x) {} // compiler error!
X f2() {} // compiler error!
Gunakan metode atau bidangnya, sebenarnya mencoba untuk mengubah variabel dengan tipe tidak lengkap
class Foo {
X *m;
void method()
{
m->someMethod(); // compiler error!
int i = m->someField; // compiler error!
}
};
Ketika datang ke template, tidak ada aturan absolut: apakah Anda dapat menggunakan tipe yang tidak lengkap karena parameter template tergantung pada cara tipe tersebut digunakan dalam template.
Misalnya, std::vector<T>
mengharuskan parameternya menjadi tipe lengkap, sementara boost::container::vector<T>
tidak. Terkadang, tipe yang lengkap diperlukan hanya jika Anda menggunakan fungsi anggota tertentu; ini adalah kasus untukstd::unique_ptr<T>
, misalnya.
Templat yang terdokumentasi dengan baik harus menunjukkan dalam dokumentasinya semua persyaratan parameternya, termasuk apakah mereka perlu tipe yang lengkap atau tidak.