مساحات الأسماء والفئات والوظائف المجانية - متى تحتاج إلى أسماء مؤهلة بالكامل
-
28-09-2019 - |
سؤال
في المثال الخاص بي أدناه ، لماذا يجب أن أتأهل تمامًا لاسم الوظيفة المجانية في 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;
}
}