سؤال

عادةً ما يتم استخدام إعلان "استخدام" لإحضار بعض وظائف الأعضاء في الفئات الأساسية التي يمكن إخفاؤها بطريقة أخرى. من وجهة النظر هذه ، فهي مجرد آلية لجعل المعلومات التي يمكن الوصول إليها أكثر ملاءمة للاستخدام.
ومع ذلك: يمكن أيضًا استخدام إعلان "استخدام" لتغيير قيود الوصول (ليس فقط للوظائف ولكن أيضًا للسمات). فمثلا:

class C{
public:
  int a;
  void g(){ cout << "C:g()\n"; }
  C() : a(0){}
};

class D : public C{
private:
  using C::a;
  using C::g;
public:
  D() { a = 1; }
};

int main(void){
  D d;
  cout << d.a << endl;  //error: a is inaccessible
  C *cp = &d;
  cout << cp->a << endl; //works
  d.g();  //error: g is inaccessible
  cp->g();  //works
  return 0;
}

أعتقد أن هذا القيد للوصول في الفئة المشتقة لا فائدة في الواقع ، لأنه يمكنك دائمًا الوصول إلى G () و A From a Pointer to the Base Class. فلا ينبغي أن يكون هناك نوع من التحذير على الأقل؟ أم أنه من الأفضل أن تمنع مثل هذا الحد من الوصول من قبل فئة مشتقة؟ لا يمثل الإعلان استخدام الإمكانية الوحيدة لإضافة قيود للوصول. يمكن أيضًا القيام به عن طريق تجاوز وظيفة فئة قاعدة وضعها في قسم مع المزيد من قيود الوصول. هل هناك بعض الأمثلة المعقولة حيث يكون من المتوقع بالفعل الحد من الوصول بهذه الطريقة؟ إذا لم يكن الأمر كذلك ، فأنا لا أرى لماذا يجب السماح به.

وشيء آخر: على الأقل مع G ++ يتجمع نفس الكود بشكل جيد بدون كلمة "باستخدام". هذا يعني على سبيل المثال أعلاه: من الممكن كتابة C :: A ؛ و C :: G ؛ بدلا من استخدام c :: a ؛ باستخدام C :: G ؛ هل أول اختصار فقط للأخير أم أن هناك بعض الاختلافات الدقيقة؟

//تعديل:
لذلك من النقاش والإجابات أسفل استنتاجي سيكون:
- يُسمح له بحد من قيود الوصول في الفصول المشتقة مع الميراث العام
- هناك أمثلة مفيدة حيث يمكن استخدامها
- قد يؤدي الاستخدام إلى مشكلة في تركيبة مع القوالب (على سبيل المثال ، لا يمكن أن تكون الفئة المشتقة معلمة صالحة لبعض فئة/وظيفة القالب بعد الآن على الرغم من أن قاعدةها)
- يجب ألا يسمح تصميم اللغة أنظف بهذا الاستخدام
- يمكن للمترجم على الأقل إصدار نوع من التحذير

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

المحلول

فيما يتعلق بإعلانك بدون using: هذه تسمى "إعلانات الوصول" ، ويتم إهمالها. هنا النص من المعيار ، من 11.3/1:

يمكن تغيير وصول أحد أعضاء الفصل الأساسي في الفئة المشتقة من خلال ذكر معرفته المؤهلة في إعلان الفئة المشتقة. مثل هذا الذكر يسمى إعلان الوصول. تأثير إعلان الوصول qualified-id; يُعرّف بأنه مكافئ للإعلان usingqualified-id; الحاشية: يتم إهمال إعلانات الوصول ؛ عضو باستخدام الأسماء (7.3.3) توفير وسيلة أفضل لفعل نفس الأشياء. في الإصدارات السابقة من لغة C ++ ، كانت إعلانات الوصول أكثر محدودة ؛ تم تعميمهم وجعلوا مكافئين ل باستخدام الأسماء - حاشية نهاية

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

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

نصائح أخرى

على الرغم من أن الإعلان الذي أظهرته يوفر آلية لتغيير مستوى الوصول (ولكن فقط لأسفل) ، فإن هذا ليس هو الاستخدام الأساسي له في مثل هذا السياق. يهدف السياق باستخدام هناك في المقام الأول للسماح بالوصول إلى الوظائف التي يمكن ظلالها من الفئة الأساسية بسبب ميكانيكا اللغة. على سبيل المثال

class A {
public:
   void A();
   void B();
};

class B {
public:
   using A::B;
   void B(int); //This would shadow A::B if not for a using declaration
};

الإعلان

using C::a

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

الإعلان لا يغير حقوق الوصول ؛ يمكنك الوصول إلى "A" في الفئة الفرعية فقط لأن "A" ليست خاصة.

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