سؤال

أنا أتساءل ما هو الفرق بين typeid و typeof في C ++. هذا ما أعرفه:

  • typeid مذكور في الوثائق ل type_info الذي يتم تعريفه في ملف رأس C ++ TypeInfo.

  • typeof تم تعريفه في امتداد GCC لـ C وفي C ++ تعزيز مكتبة.

أيضًا ، هنا اختبار رمز الاختبار الذي قمت بإنشائه حيث اكتشفت ذلك typeid لا يعيد ما كنت أتوقعه. لماذا ا؟

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)  
 }  

انتاج:

bash-3.2$ g++ -Wall main.cpp -o main  
bash-3.2$ ./main   
i  
6Person  
8Employee  
P6Person  
8Employee
هل كانت مفيدة؟

المحلول

لغة C ++ ليس لها شيء من هذا القبيل typeof. يجب أن تنظر إلى بعض التمديد الخاص بالمترجمات. إذا كنت تتحدث عن دول مجلس التعاون الخليجي typeof, ، ثم توجد ميزة مماثلة في C ++ 11 من خلال الكلمة الرئيسية decltype. مرة أخرى ، لا يوجد شيء من هذا القبيل typeof الكلمة الرئيسية.

typeid هو مشغل لغة C ++ الذي يعيد معلومات التعريف في وقت التشغيل. يعيد أساسا أ type_info الكائن ، الذي هو قابل للمساواة مع الآخرين type_info أشياء.

لاحظ أن الخاصية المحددة الوحيدة التي تم إرجاعها type_info الكائن له هو كونه مساواة وغير قابلة للأسمام ، أي type_info يجب أن تقارن الكائنات التي تصف الأنواع المختلفة غير متساوٍ type_info الكائنات التي تصف نفس النوع يجب أن تقارن متساوين. كل شيء آخر محدد للتنفيذ. الطرق التي تعيد "أسماء" مختلفة ليست مضمونة لإعادة أي شيء قابل للقراءة الإنسان ، وحتى غير مضمون لإعادة أي شيء على الإطلاق.

لاحظ أيضًا أن ما سبق على الأرجح (على الرغم من أن المعيار لا يبدو أنه يذكره بشكل صريح) typeid إلى نفس النوع قد يعود مختلفًا type_info الكائنات (والتي ، بالطبع ، لا يزال يتعين عليها مقارنة متساوية).

نصائح أخرى

الفرق الأساسي بين الاثنين هو ما يلي

  • Typeof عبارة عن بنية وقت ترجمة وإرجاع النوع على النحو المحدد في وقت الترجمة
  • TypeID هو بناء وقت التشغيل وبالتالي يقدم معلومات حول نوع وقت التشغيل للقيمة.

نوع المرجعية: http://www.delorie.com/gnu/docs/gcc/gcc_36.html

مرجع typeid: https://en.wikipedia.org/wiki/typeid

typeid يمكن أن تعمل في وقت التشغيل ، وإرجاع كائن يصف نوع وقت التشغيل للكائن ، والذي يجب أن يكون مؤشرًا لكائن فئة ذات طرق افتراضية من أجل RTTI (معلومات نوع وقت التشغيل) لتخزينها في الفصل. يمكن أن يمنح أيضًا نوع وقت الترجمة للتعبير أو اسم النوع ، إن لم يتم إعطاؤه مؤشرًا إلى فئة مع معلومات نوع وقت التشغيل.

typeof هو امتداد GNU ، ويمنحك نوع أي تعبير في وقت الترجمة. قد يكون هذا مفيدًا ، على سبيل المثال ، في إعلان المتغيرات المؤقتة في وحدات الماكرو التي يمكن استخدامها في أنواع متعددة. في C ++ ، عادة ما تستخدم قوالب في حين أن.

الإجابة على السؤال الإضافي:

لا يخرج رمز الاختبار التالي لـ TypeID اسم النوع الصحيح. ماالخطب؟

ليس هناك أي خطأ. ما تراه هو تمثيل السلسلة لاسم النوع. لا يجبر C ++ القياسي على المترجمين على إصدار الاسم الدقيق للفصل ، فالأمر متروك للمنفذ (بائع المترجم) لتحديد ما هو مناسب. باختصار ، الأسماء تصل إلى المترجم.


هذه أداتان مختلفتان. typeof إرجاع نوع التعبير ، لكنه ليس قياسيًا. في C ++ 0x هناك شيء يسمى decltype الذي يفعل نفس الوظيفة afaik.

decltype(0xdeedbeef) number = 0; // number is of type int!
decltype(someArray[0]) element = someArray[0];

بينما typeid يستخدم مع أنواع الأشكال. على سبيل المثال ، دعنا نقول ذلك cat مشتق animal:

animal* a = new cat; // animal has to have at least one virtual function
...
if( typeid(*a) == typeid(cat) )
{
    // the object is of type cat! but the pointer is base pointer.
}

يوفر TypeID نوع البيانات في وقت التشغيل ، عند الطلب. Typedef هو بنية وقت الترجمة التي تحدد نوعًا جديدًا كما هو مذكور بعد ذلك. لا يوجد أي نوع في إخراج C ++ يظهر على أنه (يظهر كتعليقات منقوشة):

std::cout << typeid(t).name() << std::endl;  // i
std::cout << typeid(person).name() << std::endl;   // 6Person
std::cout << typeid(employee).name() << std::endl; // 8Employee
std::cout << typeid(ptr).name() << std::endl;      // P6Person
std::cout << typeid(*ptr).name() << std::endl;     //8Employee

يمكنك استخدام تشكيل Boost لإنجاز اسم جميل المظهر:

#include <boost/units/detail/utility.hpp>

وشيء مثل

To_main_msg_evt ev("Failed to initialize cards in " + boost::units::detail::demangle(typeid(*_IO_card.get()).name()) + ".\n", true, this);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top