چرا زمان عوض کردن ترتیب مقدار دادن به اعضای کلاس در constructor Initializer کامپایلر warning میده ؟ - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

چرا زمان عوض کردن ترتیب مقدار دادن به اعضای کلاس در constructor Initializer کامپایلر warning میده ؟

+5 امتیاز

من زمان استفاده از : برای مقدار دادن به اعضای کلاس به این شکل عمل کردم :

class A
{
public:
    A():
        b(2),
        a(1)
    {}

private:
    int a;
    int b;
};

 

ولی کامئایلر warning میده که  'A::b' will be initialized after [-Wreorder]
  دلیل چیه ؟
        

سوال شده اسفند 7, 1392  بوسیله ی مریم اکرمی (امتیاز 482)   25 55 66
دوباره تگ گذاری شد مهر 9, 1393 بوسیله ی BlueBlade

2 پاسخ

+5 امتیاز
 
بهترین پاسخ

دلیلش اینه که کامپایلر به اون ترتیبی که در constructor iniitializer مقدار میدین مقدار نمیده بلکه به ترتیبی که در کلاس تعریف شدن مقدار میده و از اون جایی که شما اول a رو توی کلاس مقدار میدین بعد b رو ولی توی constructor iniitializer بر عکس مقدار دادین کامپایلر به شما هشدار میده که به ترتیبی که وارد کردین اعضا مقدار نمی گیرین

  البته توی کد شما چون هر 2 تا int هستن مشکلی ایجاد نمیشه ولی اگر a وابسته به b بود مشکل ایجاد میشد مثلا کد زیر چون اول x مقدار می گیره بعد y زمان اجرا ارور میده (چون x از y که هنوز ساخته نشده استفاده می کنه )

#include <iostream>;

using namespace std;

class A
{
public:
    A():y("name"),
        x(y)
    {}
    
private:
    string x;
    string y;
};


int main()
{
    A a;
}



 

 

پاسخ داده شده اسفند 7, 1392 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
انتخاب شد اسفند 28, 1392 بوسیله ی مریم اکرمی
0 امتیاز

به این علت که کامپایلر متغیرهای عضو یک کلاس را در یک section به نام data تعریف میکنه که دقیقا به صورت ترتیبی هستند و بنابراین زمانی که لینکر باید آدرسها را از جداول آدرس دهی استخراج کنه تا برای این متغییر های تعریف شده در این سکشن آدرس های فیزیکی مشخص کنه آدرسها هم به صورت ترتیبی خواهند بود، بنابراین با استفاده از آدرس فیزیکی متغییر با توجه به نوع اون یک مقدار اولیه در استک تعریف میکنه، بنابراین کامپایلر با نام هایی که ما در برنامه تعریف میکنیم کاری نداره و اصلا اونها را نمیشناسه فقط با آدرس اونها کار داره! به همین علت اگر این ترتیب را در زمان تعریف رعایت نکنید داده ها در حافظه دچار همپوشانی خواهند شد. 

البته اگر شما به صورت غیر مستقیم در خود سازنده مقدار دهی کنید یعنی به صورت زیر...

class A
{
public:
    A() {
     b=1;
     a=2;
}
 
private:
    int a;
    int b;
}

دیگه مهم نیست که ترتیب تعریف متغییرهای عضو کلاس را در زمان مقدار دهی رعایت کنید، رعایت ترتیب مقداردهی در زمان استفاده از direct initializer ctor مهم هست

پاسخ داده شده اردیبهشت 22, 1399 بوسیله ی فرهاد شیری (امتیاز 97)   1 3
...