c++ - دالة بنفس الاسم ولكن توقيع مختلف في فئة مكتسبة




function inheritance (2)

لدي وظيفة تحمل الاسم نفسه ، ولكن مع توقيع مختلف في فصول دراسية أساسية ومشتقة. عندما أحاول استخدام وظيفة الفئة الأساسية في فئة أخرى ترث من المشتق ، أتلقى خطأً. انظر الكود التالي:

class A
{
    public:
    void foo(string s){};
};

class B : public A
{
    public:
    int foo(int i){};
};

class C : public B
{
    public:
    void bar()
    {
        string s;
        foo(s);
    }
};

أتلقى الخطأ التالي من المترجم gcc:

In member function `void C::bar()': no matching function for call to `C::foo(std::string&)' candidates are: int B::foo(int)

إذا قمت بإزالة int foo(int i){}; من الطبقة B ، أو إذا foo1 تسميتها من foo1 ، foo1 شيء يعمل بشكل جيد.

ما المشكلة في هذا؟


ذلك لأن البحث عن الاسم يتوقف إذا وجد اسمًا في إحدى قواعدك. لن ننظر إلى أبعد من ذلك في قواعد أخرى. تعمل الدالة B في الظلال على الوظيفة في A. يجب عليك إعادة الإعلان عن الدالة A في نطاق B ، بحيث تظهر كلتا الدالتين من B و C:

class A
{
    public:
    void foo(string s){};
};

class B : public A
{
    public:
    int foo(int i){};
    using A::foo;
};

class C : public B
{
    public:
    void bar()
    {
        string s;
        foo(s);
    }
};

تحرير: الوصف الحقيقي الذي يعطيه المعيار (من 10.2 / 2):

تعريف الخطوات التالية نتيجة البحث عن اسم في نطاق فئة ، C. أولاً ، يتم اعتبار كل تعريف الاسم في الفئة وفي كل من الكائنات الفرعية فئة الأساسية الخاصة به. اسم عضو f في كائن فرعي واحد B يخفي اسم عضو f في كائن فرعي A إذا كان A كائنًا فرعيًا أساسيًا من الفئة B. أي إعلانات مخفية بحيث يتم استبعادها من الاعتبار. يعتبر كل إعلان من هذه التعريفات الذي تم تقديمه من خلال تصريح استخدام من كل كائن فرعي من C ، وهو من النوع الذي يحتوي على الإعلان المعين من قبل-إعلان .96) إذا لم تكن مجموعة الإعلانات الناتجة كلهم من كائنات فرعية من نفس النوع ، أو المجموعة لها عضو غير ساكن وتضم أعضاء من كائنات فرعية مميزة ، هناك غموض والبرنامج غير مشكل. وإلا فإن هذه المجموعة هي نتيجة البحث.

لديه ما يلي ليقول في مكان آخر (فقط فوقها):

بالنسبة إلى التعبير التعريفي [ شيء مثل "foo" ] ، يبدأ البحث عن الاسم في نطاق الفصل الدراسي لهذا ؛ للحصول على معرف مؤهل [ شيء مثل "A :: foo" ، A هو محدد متداخل للاسم ] ، يبدأ البحث عن الاسم في نطاق محدد الاسم المتداخل. يتم البحث عن الاسم قبل التحكم في الوصول (3.4 ، بند 11).

([...] وضعه لي). لاحظ أن هذا يعني أنه حتى إذا كان foo الخاص بك في B خاص ، فلن يتم العثور على foo في A (لأن التحكم في الوصول يحدث لاحقًا).


وظائف في الفئات المشتقة التي لا تتخطى الدالات في الفصول الدراسية الأساسية والتي لها نفس الاسم ستخفي وظائف أخرى بنفس الاسم في الفئة الأساسية.

يُنظر عمومًا إلى الممارسة السيئة لوجود وظائف في الفئات المشتقة التي لها نفس اسم الوظائف في فئة الباس التي لا تهدف إلى تجاوز وظائف الطبقة الأساسية لأن ما تراه ليس سلوكًا مرغوبًا في العادة. عادة ما يفضل إعطاء وظائف مختلفة أسماء مختلفة.

إذا كنت بحاجة إلى استدعاء الوظيفة الأساسية ، فستحتاج إلى توسيع نطاق الاتصال باستخدام A::foo(s) . لاحظ أن هذا من شأنه أيضًا تعطيل أي آلية دالة ظاهرية لـ A::foo(string) في نفس الوقت.







c++-faq