Mengapa kompiler tidak membiarkan saya meneruskan menyatakan typedef?
Dengan asumsi itu tidak mungkin, apa praktik terbaik untuk menjaga pohon inklusi saya tetap kecil?
c++
typedef
forward-declaration
pengguna96825
sumber
sumber
typedef
nama tipe templat bertingkat kompleks menggunakan deklarasi maju cara ini agak rumit dan sulit. Belum lagi bahwa itu mungkin memerlukan menyelam ke detail implementasi yang disembunyikan dalam argumen template default. Dan solusi akhirnya adalah kode yang panjang dan tidak dapat dibaca (terutama ketika jenis berasal dari berbagai ruang nama) sangat rentan terhadap perubahan dalam jenis aslinya.Bagi Anda seperti saya, yang ingin maju mendeklarasikan struct C-style yang didefinisikan menggunakan typedef, dalam beberapa kode c ++, saya telah menemukan solusi yang berjalan sebagai berikut ...
sumber
Untuk "fwd mendeklarasikan typedef" Anda perlu fwd mendeklarasikan kelas atau struct dan kemudian Anda dapat mengetikkan typeed yang dideklarasikan. Beberapa typedef identik dapat diterima oleh kompiler.
bentuk panjang:
bentuk pendek:
sumber
Di C ++ (tapi bukan C biasa), sangat sah untuk mengetikkan tipe dua kali, asalkan kedua definisi benar - benar identik:
sumber
A
bidang dengan cara ini karenaA
kosong menurut definisi?Karena untuk mendeklarasikan suatu tipe, ukurannya perlu diketahui. Anda dapat meneruskan mendeklarasikan pointer ke tipe, atau mengetikkan pointer ke tipe.
Jika Anda benar-benar ingin, Anda dapat menggunakan idiom pimpl untuk menjaga agar menyertakan. Tetapi jika Anda ingin menggunakan tipe, daripada pointer, kompiler harus mengetahui ukurannya.
Sunting: j_random_hacker menambahkan kualifikasi penting untuk jawaban ini, pada dasarnya ukuran itu perlu diketahui untuk menggunakan tipe tersebut, tetapi deklarasi maju dapat dibuat jika kita hanya perlu mengetahui tipe yang ada , untuk membuat pointer atau referensi ke Tipe. Karena OP tidak menunjukkan kode, tetapi mengeluh itu tidak dapat dikompilasi, saya berasumsi (mungkin dengan benar) bahwa OP sedang mencoba menggunakan tipe tersebut, tidak hanya merujuknya.
sumber
Menggunakan penerusan deklarasi alih - alih
#include
s penuh hanya dimungkinkan bila Anda tidak bermaksud menggunakan tipe itu sendiri (dalam cakupan file ini) tetapi sebuah pointer atau referensi untuk itu.Untuk menggunakan tipe itu sendiri, kompiler harus mengetahui ukurannya - maka deklarasi lengkapnya harus dilihat - maka diperlukan penuh
#include
.Namun, ukuran pointer atau referensi diketahui oleh kompiler, terlepas dari ukuran pointee, sehingga pernyataan maju sudah cukup - itu menyatakan nama pengenal jenis.
Menariknya, ketika menggunakan pointer atau referensi
class
ataustruct
tipe, kompiler dapat menangani tipe yang tidak lengkap sehingga Anda tidak perlu meneruskan menyatakan tipe pointee juga:sumber
Saya memiliki masalah yang sama, tidak ingin dipusingkan dengan beberapa typedef dalam file yang berbeda, jadi saya menyelesaikannya dengan warisan:
dulu:
melakukan:
Bekerja seperti pesona. Tentu saja, saya harus mengubah referensi apa pun dari
untuk sederhana
sumber
Saya mengganti
typedef
(using
lebih spesifik) dengan warisan dan konstruktor (?).Asli
Diganti
Dengan cara ini saya bisa maju menyatakan
CallStack
dengan:sumber
Seperti yang dicatat oleh Bill Kotsias, satu-satunya cara yang masuk akal untuk menjaga detail typedef poin Anda tetap pribadi, dan meneruskannya adalah dengan warisan. Anda dapat melakukannya sedikit lebih baik dengan C ++ 11 sekalipun. Pertimbangkan ini:
sumber
Seperti @BillKotsias, saya menggunakan warisan, dan itu berhasil untuk saya.
Saya mengubah kekacauan ini (yang mengharuskan semua tajuk boost dalam deklarasi saya * .h)
dalam deklarasi ini (* .h)
dan implementasinya (* .cpp) tadinya
sumber