الخطأ الحجة التحويل المفضل عند استدعاء الدالة

StackOverflow https://stackoverflow.com/questions/663724

سؤال

أنا أكتب برنامج MS Visual C++ 6.0 (نعم ، أنا أعلم أنه القديمة, لا يوجد شيء يمكنني القيام به لرفع مستوى).أنا أرى بعض السلوك الذي أعتقد أنه أمر غريب حقا.لدي الدرجة مع اثنين من منشئات محددة مثل هذا:

class MyClass
{
public:
    explicit MyClass(bool bAbsolute = true, bool bLocation = false) : m_bAbsolute(bAbsolute), m_bLocation(bLocation) { ; }
    MyClass(const RWCString& strPath, bool bLocation = false);

private:
    bool m_bAbsolute;
    bool m_bLocation;
};

عندما كنت إنشاء مثيل من هذه الفئة مع هذه الجملة: MyClass("blah"), ويدعو إلى المنشئ الأول.كما ترون لقد تم إضافة explicit الكلمة في أمل أنه لن يفعل ذلك...لا الزهر.ويبدو أن تفضل التحويل من const char * إلى bool على التحويل RWCString, الذي لديه نسخة منشئ الذي يأخذ const char *.لماذا يفعل هذا ؟ أود أن نفترض أن تعطى اثنين من الخيارات الممكنة مثل هذا, فإنه يقول انها غامضة.ما الذي يمكنني القيام به لمنع ذلك من فعل هذا ؟ إذا كان ذلك ممكنا ، أود أن تجنب الاضطرار إلى صراحة يلقي strPath الحجة إلى RWCString, كما انها سوف تستخدم مع حرفية الكثير و الكثير من كتابة إضافية (بالإضافة إلى الحقيقة من الخطأ أن تجعل).

هل كانت مفيدة؟

المحلول

والصريح لن يساعد هنا كما المنشئ ليست جزءا من التحويل الضمني، فقط المستلم.

وليس هناك طريقة للتحكم في الترتيب المفضل من التحويلات، ولكن هل يمكن إضافة منشئ الثانية التي أخذت شار CONST *. منها مثلا:

class MyClass
{
public:
    MyClass(bool bAbsolute = true, bool bLocation = false);
    MyClass(const RWCString& strPath, bool bLocation = false);
    MyClass(const char* strPath, bool bLocation = false);

private:
    bool m_bAbsolute;
    bool m_bLocation;
};

نصائح أخرى

وقدم أندرو غرانت الحل. أريد أن أقول لكم <م> لماذا لا يعمل بالطريقة التي حاول. إذا كان لديك اثنين من وظائف قابلة للحجة، ثم يسمى واحد يطابق الحجة أفضل. والثاني يتطلب تحويل المعرفة من قبل المستخدم، في حين أن الأول يحتاج فقط لتحويل القياسية. وهذا هو السبب في أن المترجم يفضل الاول على الثاني.

إذا كنت ارتداء؛ ر تريد أن تبقي الصب ذلك، فإنه يبدو لي أنه قد يكون لديك لجعل المنشئ آخر أن يأخذ شار CONST *

.

وهذا ما أود أن تفعل ربما في هذه الحالة.

و(يدري لماذا كنت ترغب بجعل المنشئ مع النوع الذي لا يمر لأكثر من استخدامه لا).

وتحرير:

وأرى شخص آخر نشر هذا بالفعل بينما كنت تكتب الألغام

ولا يدري لماذا يجب أن نخلط بين إشارة إلى سلسلة ومنطقي؟ لقد رأيت مشاكل مع منطقي وكثافة العمليات.
يمكنك أن تفقد القيمة الافتراضية لالمنشئ الأول - قد يكون ذلك لأن هذا يجعل من منشئ الافتراضي لMyClass () ثم هو أيضا الافتراضي إذا كان لا يمكن أن تتطابق مع وسائط

واختياراتك هي لإضافة منشئ التي تأخذ صراحة CONST شار *

MyClass(const char* strPath, bool bLocation = false); // Thanks Andrew Grant!

وأو القيام

MyClass( string("blah") );

والمترجم يعرف جوهرها كيفية جعل تشار CONST * في منطقي. فإنه سيتعين عليها أن تذهب تبحث لمعرفة ما إذا، لأي من أنواع الحجة الأولى من الصانعين MyClass، وهناك منشئ التي سوف تتخذ نوع المصدر الذي أعطيت له، أو إذا كان يمكن أن يطرح للالنوع الذي يقبله أي من المنشئات من أي نوع من أنواع الحجة الأولى من الصانعين MyClass الخاص بك، أو ... حسنا، ترى أين يحدث هذا وهذا فقط من أجل الوسيطة الأولى. بهذه الطريقة تكمن الجنون.

والكلمة explicit يقول المترجم أنه لا يمكن تحويل قيمة من نوع حجة وإلى كائن من الفئة الخاصة بك ضمنا، كما في

struct C { explicit C( int i ): m_i(i) {}; int m_i; };
C c = 10;//disallowed
C c( 2.5 ); // allowed

وC ++ يحتوي على مجموعة من القواعد لتحديد ما منشئ هو ليتم استدعاؤها في حالتك - أنا لا أعرف من الجزء الخلفي من رأسي لكن يمكنك أن ترى حدسي أن الحجج الافتراضي تؤدي نحو الغموض

وتحتاج إلى أن تلك الافتراضات من خلال.

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

struct C {
  static C fromString( const char* s, const bool b = true );
  static C fromBools( const bool abs = true, const bool b = true );
};

أو

struct CBase {
    bool absolute; 
    bool location;
    CBase( bool abs=true, bool loc=true );
};

struct CBaseFromPath {
    // makes 'absolute' true if path is absolute
    CBaseFromPath( const char* s, const bool loc );
};

أنت بعض أنه حقا هو الدعوة أول منشئ ؟ تتصل مع سلسلة ترميز-الثابت ، أو هو مخفي وراء #define?هل أنت متأكد من أن #تعريف هو ما كنت أعتقد أنه هو ؟ (محاولة ترجمة مع /Ef الخيار للحصول على توسيع المعالج الإخراج ، ومعرفة ما إذا كان استدعاء يبدو أنك تتوقع أن تبدو.)

تحرير:وبناء على هذه التعليقات ، اقتراحي هو إضافة أخرى منشئ const char*. غير أن ذلك ممكنا ؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top