Saya bertanya-tanya apa perbedaan antara typeid
dan typeof
di C ++. Inilah yang saya tahu:
typeid
disebutkan dalam dokumentasi untuk type_info yang didefinisikan di C ++ file header TypeInfo .typeof
didefinisikan dalam ekstensi GCC untuk C dan di pustaka C ++ Boost .
Juga, ini adalah tes kode tes yang saya buat di mana saya telah menemukan yang typeid
tidak mengembalikan apa yang saya harapkan. Mengapa?
main.cpp
#include <iostream>
#include <typeinfo> //for 'typeid' to work
class Person {
public:
// ... Person members ...
virtual ~Person() {}
};
class Employee : public Person {
// ... Employee members ...
};
int main () {
Person person;
Employee employee;
Person *ptr = &employee;
int t = 3;
std::cout << typeid(t).name() << std::endl;
std::cout << typeid(person).name() << std::endl; // Person (statically known at compile-time)
std::cout << typeid(employee).name() << std::endl; // Employee (statically known at compile-time)
std::cout << typeid(ptr).name() << std::endl; // Person * (statically known at compile-time)
std::cout << typeid(*ptr).name() << std::endl; // Employee (looked up dynamically at run-time
// because it is the dereference of a pointer
// to a polymorphic class)
}
keluaran:
bash-3.2$ g++ -Wall main.cpp -o main
bash-3.2$ ./main
i
6Person
8Employee
P6Person
8Employee
name()
ditentukan oleh implementasi. Itu tidak harus nama pengenal C ++ yang valid, hanya sesuatu yang secara unik mengidentifikasi jenisnya. Sepertinya implementasi Anda menggunakan skema penyusunan-nama umum kompiler.Jawaban:
Bahasa C ++ tidak memiliki yang namanya
typeof
. Anda harus melihat beberapa ekstensi khusus-kompiler. Jika Anda berbicara tentang GCCtypeof
, maka fitur serupa ada di C ++ 11 melalui kata kuncidecltype
. Sekali lagi, C ++ tidak memilikitypeof
kata kunci seperti itu .typeid
adalah operator bahasa C ++ yang mengembalikan informasi identifikasi jenis pada waktu berjalan. Ini pada dasarnya mengembalikantype_info
objek, yang setara dengantype_info
objek lain .Perhatikan, bahwa satu-satunya properti yang didefinisikan dari
type_info
objek yang dikembalikan adalah yang setara dan setara, yaitutype_info
objek yang menggambarkan tipe yang berbeda harus membandingkan yang tidak sama, sedangkantype_info
objek yang menggambarkan tipe yang sama harus membandingkan yang sama. Segala sesuatu yang lain ditentukan oleh implementasi. Metode yang mengembalikan berbagai "nama" tidak dijamin untuk mengembalikan apa pun yang dapat dibaca oleh manusia, dan bahkan tidak dijamin untuk mengembalikan apa pun.Perhatikan juga, bahwa hal di atas mungkin menyiratkan (meskipun standar tampaknya tidak menyebutkannya secara eksplisit) bahwa aplikasi berurutan
typeid
untuk tipe yang sama dapat mengembalikantype_info
objek yang berbeda (yang, tentu saja, masih harus membandingkan sama).sumber
decltype
? Saya tidak yakin apa itu kebijakan umum, tetapi karena pertanyaan itu ditandai,C++
saya akan mengharapkannya merujuk pada standar terbaru. Retagging pertanyaan sepertiC++03
itu juga akan menjadi pilihan imho. Saya pribadi kadang-kadang agak bingung, karena saya harus menggunakan preC ++ 11 di tempat kerja dan kadang-kadang saya tidak yakin apa yang benar "pre11" atau "post11".decltype
bukan penggantitypeof
.typeof
bekerja pada tipe juga sementaradecltype
tidak. Sebagai contoh,typeof(int)
adalahint
ketikadecltype(int)
kesalahan.type_info
objek yang menggambarkan tipe berbeda harus membandingkan yang tidak sama" . Sebenarnya, ini tidak dijamin . Operator ketidaksetaraan dihapus dalam C ++ 20 untuk (saya berasumsi) mencegah mengandalkan berbagai jenis membandingkan non-sama. Tetapi jika Anda memikirkannya, kesetaraan tidak aman jika ketidaksetaraan tidak aman.Perbedaan utama antara keduanya adalah sebagai berikut
typeof Referensi: http://www.delorie.com/gnu/docs/gcc/gcc_36.html
Referensi typeid: https://en.wikipedia.org/wiki/Typeid
sumber
typeid
dapat beroperasi pada saat runtime, dan mengembalikan sebuah objek yang menggambarkan tipe run time dari objek, yang harus menjadi pointer ke objek kelas dengan metode virtual agar RTTI (informasi tipe run-time) disimpan di kelas. Itu juga dapat memberikan tipe waktu kompilasi dari ekspresi atau nama tipe, jika tidak diberi pointer ke kelas dengan informasi tipe run-time.typeof
adalah ekstensi GNU, dan memberi Anda jenis ekspresi apa pun pada waktu kompilasi. Ini bisa berguna, misalnya, dalam mendeklarasikan variabel sementara dalam makro yang dapat digunakan pada banyak jenis. Di C ++, Anda biasanya menggunakan templat .sumber
typeid
akan menerima ekspresi apa pun, bukan hanya yang mengevaluasi objek dengan metode virtual. Selanjutnya,typeid
akan menerima nama jenis , bukan hanya ekspresi. Anda dapat mengatakantypeid(5)
atautypeid(std::string)
jika Anda mau.typeid
dapat mengembalikan informasi jenis run-time jika tersedia, tetapi akan memberikan informasi tipe waktu kompilasi untuk hal lain.Menjawab pertanyaan tambahan:
Tidak ada yang salah. Apa yang Anda lihat adalah representasi string dari nama tipe. C ++ standar tidak memaksa kompiler untuk memancarkan nama kelas yang tepat, hanya terserah pelaksana (vendor kompiler) untuk memutuskan apa yang cocok. Singkatnya, nama-nama terserah kompiler.
Ini adalah dua alat yang berbeda.
typeof
mengembalikan tipe ekspresi, tetapi tidak standar. Di C ++ 0x ada sesuatu yang disebutdecltype
AFAIK yang melakukan pekerjaan yang sama.Padahal
typeid
digunakan dengan tipe polimorfik. Misalnya, katakanlah yangcat
berasalanimal
:sumber
typeid menyediakan tipe data pada saat runtime, ketika diminta. Typedef adalah konstruk waktu kompilasi yang mendefinisikan tipe baru seperti yang dinyatakan setelah itu. Tidak ada typeof di C ++ Output muncul sebagai (ditampilkan sebagai komentar tertulis):
sumber
Anda dapat menggunakan Boost demangle untuk mendapatkan nama yang terlihat bagus:
dan sesuatu seperti
sumber