سؤال

هل يمكن لأي شخص أن يشرح سبب عدم تجميع التعليمات البرمجية التالية؟على الأقل على g++ 4.2.4.

والأكثر إثارة للاهتمام، لماذا سيتم تجميعه عندما أقوم بإلقاء MEMBER على int؟

#include <vector>

class Foo {  
public:  
    static const int MEMBER = 1;  
};

int main(){  
    vector<int> v;  
    v.push_back( Foo::MEMBER );       // undefined reference to `Foo::MEMBER'
    v.push_back( (int) Foo::MEMBER ); // OK  
    return 0;
}
هل كانت مفيدة؟

المحلول

وتحتاج إلى تعريف الواقع عضو ثابت في مكان ما (بعد تعريف الفئة). جرب هذا:

class Foo { /* ... */ };

const int Foo::MEMBER;

int main() { /* ... */ }

وهذا يجب أن نتخلص من إشارة غير محددة.

نصائح أخرى

والمشكلة تأتي بسبب اشتباك مثيرة للاهتمام من الميزات الجديدة C ++ وما نحاول القيام به. أولا، دعونا نلقي نظرة على التوقيع push_back:

void push_back(const T&)

وانها تتوقع إشارة إلى كائن من نوع T. في ظل النظام القديم من التهيئة، يوجد هذا العضو. على سبيل المثال، التعليمة البرمجية التالية يجمع ما يرام:

#include <vector>

class Foo {
public:
    static const int MEMBER;
};

const int Foo::MEMBER = 1; 

int main(){
    std::vector<int> v;
    v.push_back( Foo::MEMBER );       // undefined reference to `Foo::MEMBER'
    v.push_back( (int) Foo::MEMBER ); // OK  
    return 0;
}

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

#define MEMBER 1

ولكن من دون الصداع من ماكرو المعالج (ومع السلامة نوع). وهذا يعني أنه متجه، التي تنتظر إشارة، لا يمكن الحصول على واحد.

يتطلب معيار C++ تعريفًا لعضو const الثابت الخاص بك إذا كان التعريف مطلوبًا بطريقة ما.

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

عندما تقوم بإلقاء الثابت بشكل صريح، فإنك تقوم بإنشاء مؤقت وهذا المؤقت هو المرتبط بالمرجع (بموجب قواعد خاصة في المعيار).

هذه حالة مثيرة للاهتمام حقًا، وأعتقد في الواقع أن الأمر يستحق إثارة مشكلة بحيث يتم تغيير المعيار ليكون له نفس السلوك بالنسبة لعضوك الدائم!

على الرغم من أنه بطريقة غريبة يمكن اعتبار ذلك استخدامًا مشروعًا للمشغل الأحادي "+".في الأساس نتيجة unary + هي قيمة r وبالتالي تنطبق قواعد ربط قيم r بمراجع const ولا نستخدم عنوان عضو const الثابت الخاص بنا:

v.push_back( +Foo::MEMBER );

آآ.ح

class Aaa {

protected:

    static Aaa *defaultAaa;

};

AAA.cpp

// You must define an actual variable in your program for the static members of the classes

static Aaa *Aaa::defaultAaa;

ولا فكرة لماذا يعمل المدلى بها، ولكن فو :: لم يتم تخصيص عضو حتى المرة الأولى التي يتم تحميلها فو، ومنذ كنت أبدا تحميله، انها خصصت أبدا. إذا كان لديك إشارة إلى فو في مكان ما، فإنه من المحتمل أن العمل.

وفيما يتعلق بالسؤال الثاني: push_ref يأخذ إشارة كمعلمة، وأنت لا يمكن أن يكون إشارة إلى تشادي CONST ثابت من فئة / البنية. وبمجرد الاتصال static_cast، يتم إنشاء متغير مؤقت. وإشارة إلى هذا الكائن يمكن أن تنتقل، كل شيء يعمل على ما يرام.

وأو على الأقل زميلي الذي حل هذا قال ذلك.

ومع C ++ 11، ما سبق سيكون من الممكن لأنواع الأساسية ك

class Foo {
public:  
  static constexpr int MEMBER = 1;  
};

والجزء constexpr يخلق ثابت <م> التعبير بدلا من ثابت <م> متغير - وأن يتصرف تماما مثل تعريف أسلوب مضمنة بسيط للغاية. تبين أن الأسلوب المتذبذب بعض الشيء مع constexprs C سلسلة داخل الطبقات قالب، وإن كان.

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