إعلان فئة الصديق واستخدام التوجيه
-
21-12-2019 - |
سؤال
هل المثال التالي جيد الصياغة؟
namespace N {
class A;
}
using namespace N;
class B {
int i;
friend class A;
};
namespace N {
class A {
B m;
int get() { return m.i; }
};
}
تم تجميع هذا المثال بنجاح باستخدام Clang 3.5، لكنه فشل مع g++ 4.8.1 مع ما يلي:
main.cpp: In member function ‘int N::A::get()’:
main.cpp:7:9: error: ‘int B::i’ is private
int i;
^
main.cpp:14:30: error: within this context
int get() { return m.i; }
^
يقول معيار C++ 11 §7.3.1.2 p3،
إذا كان الاسم في
friend
الإعلان غير مؤهل ولا أ معرف القالب والإعلان هو وظيفة أو محدد النوع المفصل, ، فإن البحث لتحديد ما إذا كان الكيان قد تم الإعلان عنه مسبقًا يجب ألا يأخذ في الاعتبار أي نطاقات خارج مساحة الاسم الأعمق.
في المثال، class A
ليس عضوا في مساحة الاسم المغلقة الأعمق (أي.مساحة الاسم العالمية)، ولكن class A
يتم تقديمه باستخدام التوجيه في مساحة الاسم العالمية.
المحلول
أثناء استخدام مساحة الاسم N، يتم سحب الاسم N::A إلى مساحة الاسم العامة، ولا يتم الإعلان عن ذلك A في مساحة الاسم العامة.ومن ثم فإن A الإضافي في مساحة الاسم العالمية هو صديق B.رنة خاطئة.
نصائح أخرى
ليصنع N::A
بدون مؤهل أ friend
ل B
ستستخدمه
friend A;
بدلا من
friend class A;
عند استخدام محدد نوع مفصل، على سبيل المثال، class A
, ، وفي هذا النموذج المحدد، يقدم اسم فئة (انظر 3.4.4 [basic.lookup.elab] الفقرة 2).