إذا سألت أحد مبرمجي C ++ عن معنى الكلمة المفتاحية الصريحة ، فسوف يجيب معظمهم على أن هذه الكلمة الرئيسية وضعت قبل إعلان المنشئ بمعلمة واحدة (أو مع عدد كبير من المعلمات ، ولكن عندما تكون جميع المعلمات ، بدءًا من الثانية ، تحتوي على قيم افتراضية) وتمنع التحويل الضمني أنواع عند التهيئة.
class Simple { public: Simple(int a) : a_(a) {} private: int a_; }; class SimpleExplicit { public: explicit SimpleExplicit(int a) : a_(a) {} private: int a_; }; template <typename S> void someFunc(const S& s) { } int main(int, char**) { Simple s3 = 11; // SimpleExplicit se3 = 11; - COMPILE ERROR SimpleExplicit se3 = SimpleExplicit(11); someFunc<Simple>(11); // someFunc<SimpleExplicit>(11); - COMPILE ERROR someFunc<SimpleExplicit>(SimpleExplicit(11)); return 0; }
في الإصدار C ++ 03 القديم الجيد ، انتهت سيناريوهات تطبيق الكلمات الرئيسية هناك ، بدءًا من الإصدار C ++ 11 ، ونطاق التوسّع الصريح: الآن أصبح من المنطقي ليس فقط في المنشئات ذات المعلمة الواحدة ، وحتى في المنشئات فقط.
في عام 2011 ، تمت إضافة التهيئة القياسية ، والتي يجب أن تنظف طرق حديقة الحيوان في تهيئة الكائنات الموروثة من C ++ من C. لن أتحدث بالتفصيل عن التهيئة العالمية هنا ، فهناك العديد من المقالات التفصيلية حول هذا الموضوع ، من السهل العثور عليها عن طريق الكلمات الرئيسية. باختصار: يُقترح تهيئة الأشياء باستخدام الأقواس المتعرجة ، في الواقع هذا الامتداد هو ما يسمى التهيئة الإجمالية الموروثة من C.
مع ظهور التهيئة الشاملة ، أصبح هناك معنى واضح للمصممين الذين لديهم 0.2.3 معلمة أو أكثر:
class Simple { public: Simple() : a_(0), b_(0) {} Simple(int a) : a_(a), b_(0) {} Simple(int a, int b) : a_(a), b_(b) {} private: int a_, b_; }; class SimpleExplicit { public: explicit SimpleExplicit() : a_(0), b_(0) {} explicit SimpleExplicit(int a) : a_(a), b_(0) {} explicit SimpleExplicit(int a, int b) : a_(a), b_(b) {} private: int a_, b_; }; template <typename S> void someFunc(const S& s) { } int main(int, char**) { Simple s4 = {}; someFunc<Simple>({}); // SimpleExplicit se4 = {}; - COMPILE ERROR SimpleExplicit se4 = SimpleExplicit{}; // someFunc<SimpleExplicit>({}); - COMPILE ERROR someFunc<SimpleExplicit>(SimpleExplicit{}); Simple s5 = {11}; someFunc<Simple>({11}); // SimpleExplicit se5 = {11}; - COMPILE ERROR SimpleExplicit se5 = SimpleExplicit{11}; // someFunc<SimpleExplicit>({11}); - COMPILE ERROR someFunc<SimpleExplicit>(SimpleExplicit{11}); Simple s6 = {11, 22}; someFunc<Simple>({11, 22}); // SimpleExplicit se6 = {11, 22}; - COMPILE ERROR SimpleExplicit se6 = SimpleExplicit{11, 22}; // someFunc<SimpleExplicit>({11, 22}); - COMPILE ERROR someFunc<SimpleExplicit>(SimpleExplicit{11, 22}); return 0; }
بالإضافة إلى ذلك ، بدءًا من الإصدار C ++ 11 ، يمكن أيضًا تطبيق الكلمة الرئيسية الصريحة على كتابة عوامل تشغيل التحويل ، والتي تحظر أيضًا الاحتجاج الضمني الخاص بها:
class Simple { public: Simple() {} operator bool() const { return true; } }; class SimpleExplicit { public: explicit SimpleExplicit() {} explicit operator bool() const { return true; } }; int main(int, char**) { Simple s7{}; bool b7 = s7; SimpleExplicit se7{}; // bool be7 = se7; - COMPILE ERROR bool be7 = static_cast<bool>(se7); return 0; }
في الختام ، أود أن أوصي باستخدام التهيئة الشاملة في أي كود جديد لـ C ++ ، وكذلك الإعلان صراحةً عن مُنشئين صريحين دائمًا ، إلا إذا كان التحويل الضمني له ما يبرره.