سؤال

وأنا لا تزال تعلم C ++، وأبدا لقد خلق حقا بمساحات بلدي من قبل. كنت تجريب معهم، وحين حصلت على معظم الأشياء إلى العمل، هناك شيء واحد أنني ما زلت لا يمكن أن يبدو للقيام به. وأود أن تكون قادرة على استدعاء أسلوب ثابت ضمن فئة دون كتابة شيء من هذا القبيل NameOfClass::method. هنا هو ما فكرت رمز يجب أن تبدو، لكنه فشل في ترجمة:

وA.h ملف،

namespace Test
{
    class A
    {
        public:
            static int foo() { return 42; }
    };
}

وmain.cpp ملف،

#include <iostream>

#include "A.h"

using namespace std;
using namespace Test::A;

int main()
{
    cout << foo() << endl;

    return 0;
}

والمترجم يعطيني:

main.cpp:6: error: ‘A’ is not a namespace-name
main.cpp:6: error: expected namespace-name before ‘;’ token
main.cpp: In function ‘int main()’:
main.cpp:10: error: ‘foo’ was not declared in this scope

هل من الممكن أن تفعل ما أحاول القيام به دون كتابة A::foo؟

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

المحلول

وليس هناك وسيلة من حوله تحتاج إلى تحديد اسم الفئة لأساليب ثابتة.

using namespace Test;

وبعد ذلك:

int answerToEverything = A::foo();

نصائح أخرى

في C ++، ل/ خاصة / لديها لقراءة رسائل الخطأ مترجم بعناية.

لاحظ أن الخطأ الأول "الخطأ: 'A' ليس اسم نطاق". هذا صحيح، A هو اسم_الفئة.

using namespace Foo; // brings in  all of foo;
using Bar::Baz // brings in only Baz from Bar

وأنت تريد أن تكتب:

using Test::A;

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

ولكن، وكما فو هو ثابت في A، فسوف لا تزال تشير إلى A :: فو صراحة. (إلا إذا كنت تفعل شيئا مثل كتابة وظيفة الحرة التي تحيل إلى A :: فو؛ بشكل عام، وهذا هو فكرة سيئة إذا كنت تفعل ذلك فقط لانقاذ بعض الكتابة)

وقد نصح بعض لا تستخدم باستخدام الإعلانات في كل شيء، بدلا التأهل الكامل لجميع الأسماء.

ولكن هذا هو (على حد تعبير Stroustrup) "مملة وعرضة للخطأ"، وأنها تحصل في طريق إعادة بيع ديون: أقول إن كنت مؤهلا تماما كل استخدام الطبقة FooMatic :: المكدس، ثم تصر الإدارة، فقط قبل " إعادة على وشك الذهاب إلى الإنتاج، والتي تستخدمها الطبقة المكدس مشابهة جدا barMatic، لأن barMatic اشترى للتو شركتك.

وكان لك مؤهل في كل مكان، وكنت تقوم به الكثير من grepping، على أمل أن التعابير المنطقية حقكم. إذا كنت تستخدم إعلانا استخدام، يمكنك جعل مجرد الإصلاح الخاص بك (مشتركة أمل) ملف الرأس. وبهذه الطريقة، إعلانا باستخدام الكثير مثل "typedef وكثافة العمليات ourInt." أو ثابت واضح أو CONST: "CONST كثافة العمليات FOO = 1؛"، حيث أنه يوفر مكان واحد لتغيير شيء ما يشار إلى العديد من الأماكن. التأهل بشكل كامل مساحة اسم في كل استخدام يأخذ بعيدا أن تستفيد.

وعلى العكس من ذلك، كان عليك استخدام التوجيه باستخدام وتقديمهم في كل من النطاق FooMatic، البقرى الخاصة بك قد تكون أكثر صعوبة، إذا يقول أصرت الإدارة على BarMatic :: فو ولكن هل لا يزال يتعين على استخدام FooMatic: باز، أي ما يعادل BarMatic ل الباز كونها لأي سبب من الأسباب غير صالحة للاستعمال.

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

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

ولا يكون "باستخدام مساحة" المسيء. استخدام مساحة الأسماء!

std::cout << Test::A::foo() << std::endl;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top