مساحات الأسماء والفئات والوظائف المجانية - متى تحتاج إلى أسماء مؤهلة بالكامل

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

سؤال

في المثال الخاص بي أدناه ، لماذا يجب أن أتأهل تمامًا لاسم الوظيفة المجانية في CPP لتجنب أخطاء الارتباط ولماذا تعمل في وظيفة الفصل بدونها؟ هل يمكنك شرح الفرق؟

ctest.h:

namespace Test
{
    int FreeFunction();

    class CTest
    {
        public:
            CTest();
            ~CTest();
    };
}

ctest.cpp:

#include "ctest.h"

using namespace Test;

// int FreeFunction()     -> undefined reference error
int Test::FreeFunction()  -> works just fine
{
    return 0;
}

CTest::CTest()                -> no need to fully qualify name, i.e. Test::CTest
{}

CTest::~CTest()
{}

شكرا على وقتك ومساعدة.

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

المحلول

int FreeFunction(void);  

هو مجرد إعلان في حين أن ما يلي هو تعريف.

class CTest 
{ 
    public: 
        CTest(); 
        ~CTest(); 
}; 

إذا كنت تريد تقديم definition for an already declared entity in a namespace (على سبيل المثال في مساحة الاسم المرفقة) ، يجب أن يكون اسمًا مؤهلاً بالكامل.

EDIT2:

هذا شيء من شأنه أن يمنحك المزيد من الوضوح. لاحظ عدم استخدام التوجيه في هذا الرمز.

namespace Test { 
    int FreeFunction(void);   // declare

    class CTest;              // declare
} 

int Test::FreeFunction(){return 0;} // define
class Test::CTest{            // define
};

int main(){}

تحرير 3: الإعلان مقابل التعريف (C ++ 0x) $ 3.1/2--

الإعلان هو تعريف ما لم تكن تعلن وظيفة دون تحديد جسم الوظيفة (8.4), ، أنه يحتوي على محدد Extern (7.1.1) أو عبارة عن توصيل رابط 25 (7.5) ولا يوجد مُهيئ أو جسم وظيفي ، ويعلن عن عضو في البيانات الثابتة في تعريف الفئة (9.4) ، إنه إعلان اسم الفصل (9.1), ، إنه عبارة عن خارقة غير معتمة (7.2) ، أو أنها إعلان typedef (7.1.3) ، وهو استخدام فيروس (7.3.3) ، و static_assert-declaration (البند 7) ، وسم السمة (جملة البند 7) ، النهر الفارغ (الفقرة 7) ، أو A-directive (7.3.4).

نصائح أخرى

في حين FreeFunction سوف حل ل Test::FreeFunction اذا أنت الرجوع إليها أو اتصل بها بعد توفير using namespace Test; خط بقدر تعريف تسير الوظيفة ، ليس لدى المترجم أي وسيلة لمعرفة ما إذا كنت تحدد وظيفة جديدة تماما FreeFunction خارج أي مساحة اسم ، أو ما إذا كنت تحدد المعلن بالفعل Test::FreeFunction. يتخلف المترجم إلى التفكير في أنك تحدد وظيفة جديدة تمامًا.

إلى عن على CTest::CTest, ومع ذلك ، أنت بالفعل بالاشارة الى الفصل Test::CTest, ، وبما أنه لا يوجد فئة أو مساحة اسم CTest خارج Test مساحة الاسم ، حسنًا ، الإشارة إلى CTest::anything لا لبس فيه. لذلك يعرف أن تعريفات المنشئ والمدمار تشير إلى فئة المساحة الداخلية CTest.

أعتقد أنه من الثمن البضع أن تدفع ، أن تكتب Test::FreeFunction.

أتمنى أن يساعدك هذا!

إذا لم تكن مؤهلاً تعريف Freefunction ، فإن المترجم لا يعرف على وجه اليقين أنك تريد توفير التنفيذ للاختبار المعلن الأمامي سابقًا :: freefunction أو للحصول على وظيفة مجانية منفصلة في مساحة الاسم الحالية.

من ناحية أخرى ، هناك طريقة واحدة فقط لحل الاسم CTest - كتعريف فئة من مساحة الاسم الاختبار. وبالتالي ، ليست هناك حاجة لتأهيلها بالكامل.

ومع ذلك ، إذا كان دقة اسم CTEST غامضة (قل أن هناك فئة أخرى من CTEST في مساحة الاسم الحالية أيضًا) ، فسيتعين عليك تأهيل إعلانات الطريقة تمامًا.

عند تطبيق وظيفة ، عادة ما أجد ، فتح مساحة الاسم. تذكر أنه يمكنك إعادة فتحها ...

// in Test.cpp
namespace Test
{
   int FreeFunction()
   {
       return 0;
   }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top