خوش آموز درخت تو گر بار دانش بگیرد، به زیر آوری چرخ نیلوفری را


آموزش زبان ++C : برخورد نامها و فضای نامی std

آموزش زبان ++C : برخورد نامها و فضای نامی std
نویسنده : امیر انصاری
فرض کنیم برای اولین بار می خواهید به منزل یکی از دوستانتان بروید، و آدرسی که به شما داده شده است آدرس زیر می باشد :

سیستم یکپارچۀ سازمانی راهکار
"کازرون، خیابان بهار، پلاک 245".



وقتی به کازرون رسیدید، نقشه خود را باز می کنید و دنبال خیابان بهار میگردید. وقتی به نقشه نگاه کردید، متوجه می شوید که در شهر کازرون دو خیابان بهار وجود دارد، یکی در سمت راست شهر و دیگری در سمت چپ شهر! حالا به کدامیک از این دو خیابان باید بروید؟ طبیعتاً باید با دوستتان تماس بگیرید و از او بپرسید که منزلش در کدام خیابان بهار است و یا اینکه راهنمایی های بیشتری از او بگیرید. چرا که آدرس فعلی گیج کننده و در عین حال ناکافی می باشد. بد نیست بدانید در خیلی از کشورها ، الزامی گذاشته اند که اسامی خیابانهای موجود در یک شهر باید یکتا و غیر تکراری باشد.

به طور مشابه، در زبان ++C نیز، لازم است تا اسامی شناسه ها (identifiers) مانند اسامی متغیرها و اسامی توابع، در یک برنامه باید غیر تکراری باشند تا با هم تداخل پیدا نکنند. اگر دو شناسه (identifier) در یک برنامه دارای اسامی مشابهی باشند، کامپایلر (compiler) یا لینکر (linker) نمی تواند آنها را از هم تفکیک کند و خطا تولید می کند. به طور کلی به این خطا تصادم نامها یا برخورد نامها گفته می شود.

یک مثال از برخورد نامگذاری ها


a.cpp :

#include "iostream"

void doSomething(int x)
{
std::cout << x;
}

b.cpp :

#include "iostream"

void doSomething(int x)
{
std::cout << x * 2;
}

main.cpp :

#include "iostream"

void doSomething(int x); // forward declaration for doSomething

int main()
{
doSomething(5);

std::cin.get();
return 0;
}

فایل های a.cpp ، b.cpp و main.cpp اگر هر کدامشان در پروژه جداگانه ای قرار داشته باشند، بدون هیچ مشکلی کامپایل خواهند شد. با این حال، اگر در یک پروژه هر دو فایل a.cpp و b.cpp را با هم قرار بدهیم، یک برخورد بین نامگذاری ها پیش خواهد آمد، چرا که تابع doSomething در هر دوی آنها با یک اسم کاملاً مشابه معرفی شده است. این مساله منجر به ایجاد خطا توسط لینکر (linker) می گردد.

اکثر مشکلات مربوط به برخورد نامگذاری ها (naming collisions) در دو مورد اتفاق می افتند :

  1. دو فایل به یک پروژه اضافه شده اند و یک تابع و یا یک متغیر سراسری (global variable) با اسم مشابه در آنها وجود دارد. که این مساله منجر به ایجاد خطا توسط لینکر (linker) خواهد شد.

  2. کدی در فایل هدر (header file) قرار دارد که دارای شناسه ای (identifier) می باشد که با بخشی از کد شما تداخل نامی پیدا می کند. در این مورد خطا توسط کامپایلر (compiler) تولید می شود. در مورد فایل هدر (header file) در درس های بعدی بیشتر بحث خواهیم کرد.

همچنانکه برنامه ها بزرگتر می شوند و شناسه های بیشتری در آنها استفاده می شود، احتمال اینکه برخورد نامگذاری پیش بیاید به طور قابل توجهی افزایش می یابد. خبر خوب اینست که در زبان ++C مکانیزم های فراوانی برای اجتناب از این خطاهای مربوط به برخورد نامگذاری ها وجود دارد. مکانیزم هایی مانند محدوده محلی (local scope) که منجر می شود تا متغیرهای موجود در یک تابع مستقل از توابع دیگر باشند، و مکانیزم فضای نامی (namespace)، که در این درس به صورت خلاصه آن را معرفی خواهیم کرد. بنابراین با وجود این مکانیزم ها نیازی نیست تا در مورد برخورد نامگذاری ها نگران باشید.

فضای نامی std


هنگامیکه زبان ++C تازه طراحی شده بود، تمامی شناسه های موجود در کتابخانه کد استاندارد ++C مانند cin و cout به صورت مستقیم در اختیار برنامه نویس ها بودند. برای همین برنامه های ++C بسیار مستعد برخورد نامگذاری ها بود، چرا که ممکن بود یکی از اسامی که شما برای شناسه هایتان انتخاب می کنید، به صورت مشابه در کتابخانه استاندارد ++C نیز وجود داشته باشد. ممکن بود کدهایی که به درستی کار می کردند، صرفاً با included کردن یک فایل جدید دچار برخورد نامگذاری شوند و دیگر به درستی کار نکنند. و یا بدتر از آن، برنامه هایی که در یک نسخه از ++C به درستی کامپایل شده بودند، در نسخه جدیدتر آن ممکن بود با خطای برخورد نامگذاری مواجه شوند، چرا که طبیعتاً در نسخه های جدیدتر کتابخانه استاندارد ++C نیز توسعه پیدا می کرد و شناسه هایش بیشتر می شد. بنابراین ++C تمامی قابلیت های موجود در کتابخانه استاندارد ++C را به ناحیه ای خاص منتقل کرد که به آن فضای نامی (namespace) گفته می شود.

درست مانند شهرهایی که در آنها قانون یکتا بودن اسامی خیابانها وجود دارد، در ++C نیز فضای نامی (namespace) تضمین می کند که تمامی شناسه های موجود در یک فضای نامی یکتا می باشند. فضای نامی در اینجا مانند شهر عمل می کند و در واقع هیچ برخورد نامگذاری بین فضاهای نامی مختلف ایجاد نخواهد شد، چرا که هر کدام مثل یک شهر مستقل می باشند.

پس حالا معلوم شد که دستور std::cout که تا به حال از آن استفاده می کردیم در واقع فقط cout می باشد و std یک فضای نامی است که ++C به کتابخانه استاندارد خودش اختصاص داده است. تمامی قابلیت های کتابخانه استاندارد ++C در یک فضای نامی با اسم std که مخفف standard می باشد، قرار داده شده اند. این فضای نامی منجر می شود تا ما دیگر نگران هم نام شدن شناسه هایمان با شناسه های موجود در کتابخانه استاندارد ++C نباشیم.

در مورد فضای نامی (namespace) در درس های آینده بیشتر صحبت خواهیم کرد و به شما یاد خواهیم داد چگونه فضای نامی (namespace) مخصوص به خودتان را ایجاد کنید. در حال حاضر، تنها چیزی که در مورد فضای نامی، واقعاً نیاز هست تا بدانید، اینست که هر وقت که شناسه ای را که بخشی از کتابخانه استاندارد ++C می باشد، مورد استفاده قرار می دهید، باید الزاماً به کامپایلر بگوییم که شناسه های مربوطه در داخل فضای نامی (namespace) با اسم std قرار دارند.

قانون : هر گاه شناسه ای را که در یک فضای نامی خاص وجود دارد، مورد استفاده قرار می دهید، باید نام آن فضای نامی را نیز در ابتدای شناسه بیاورید.

آموزش قبلی : آموزش زبان ++C : برنامه هایی با چندین فایل

آموزش بعدی : آموزش زبان ++C : فایل های هدر (Header files)



نمایش دیدگاه ها (1 دیدگاه)

دیدگاه خود را ثبت کنید:

انتخاب تصویر ویرایش حذف
توجه! حداکثر حجم مجاز برای تصویر 500 کیلوبایت می باشد.