فضای نام (Namespace)

از فضاهای نام به منظور جلوگیری از تداخل نام کلاس‌ها و توابع و گروه بندی منطقی آن‌ها مورد استفاده قرار می‌گیرد. در مثال زیر دو کلاس هم نام را در یک scope یا حوزه دید قرار دادیم که باعث بروز خطا می‌شود :

class Sample {};
class Sample {}; // Error

اولین راه برای حل این مشکل، تغییر دادن نام یکی از آن‌هاست و راه حل دیگر، قرار دادن یکی یا هر دو آن‌ها در فضای نام‌های متفاوت است تا از تداخل نام آن‌ها جلوگیری شود.

namespace MyNamespace1
{
  class Sample {};
}
 
namespace MyNamespace2
{
  class Sample {};
}

دسترسی به اعضای یک فضای نام

برای دسترسی به اعضای یک فضای نام در خارج از آن، باید نام کامل عضو مورد را بنویسید. منظور از نام کامل این است که فضای نام را قبل از نام کلاس مورد نظر بنویسید. برای این منظور، ابتدا اسم فضای نام را نوشته سپس (::) را قرار داده و در نهایت نام کلاس مورد نظر را بنویسید. به این ترتیب مشخص می‌شود هر کلاس متعلق به کدام فضای نام است.

int main()
{
    MyNamespace1::Sample s;
    MyNamespace2::Sample s;
}

فضای نام‌های تو در تو

شما می‌توانید به هر تعداد که بخواهید فضای نام‌های تو در تو (nested) داشته باشید.

namespace MyNamespace1
{
    namespace MyNamespace2 { class Sample {}; }
}

برای دسترسی به یک عضو از فضای نام داخلی، باید اسم فضای نام‌های بیرونی را قبل از آن بنویسید :

MyNamespace1::MyNamespace2::Sample s;

وارد کردن فضای نام

شما هر زمان که بخواهید از اعضای یک فضای نام استفاده کنید، مجبورید اسم فضای نام را قبل از آن‌ها بنویسید. برای اینکه مجبور نباشید هر بار این کار را انجام دهید، می‌توانید فضای نام مورد نظر خود را using کنید. برای این منظور، ابتدا کلمات کلیدی using namespace را نوشته و بعد از آن فضای نام مورد نظر خود را بنویسید.
از کلمات کلیدی using namespace ، هم می‌توانید به صورت سراسری (global) و هم به صورت محلی (local) استفاده کنید. به این ترتیب، برای دسترسی به اعضای یک فضای نام، نوشتن نام کامل عضو لازم نیست.

using namespace MyNamespace1; // global namespace import
 
int main()
{
    using namespace MyNamespace1; // local namespace import
}

از فضای نامی که به صورت سراسری using شده باشد در کل فایل سورس و از فضای نامی که به صوت محلی using شده باشد فقط در بلوکی که داخل آن تعریف شده می‌توان استفاده کرد.

وارد کردن عضو یک فضای نام

زمانی که یک فضای نام را using می‌کنید، می‌توانید به تمام اعضای آن دسترسی داشته باشید. اگر نمی‌خواهید از تمام اعضای یک فضای نام استفاده کنید و فقط به یک عضو آن نیاز دارید، با استفاده از کلمه کلیدی using ، فقط نام کامل آن عضو را بنویسید. مثال :

using MyNamespace1::Sample; // import a single namespace member

منظور نام کامل، نوشتن فضای نام قبل از نام کلاس مورد نظر است.

نام مستعار یک فضای نام

روش دیگر برای خلاصه نویسی نام کامل عضو یک فضای نام، استفاده از نام مستعار است. برای این کار ابتدا کلمه کلیدی namespace و سپس نام مستعاری که می‌خواهید را بنویسید. حال فضای نام‌های مورد نظر خود را به این نام مستعار انتساب دهید :

namespace myAlias =MyNamespace1::Sample; // namespace alias

اکنون می‌توانید از این نام مستعار هر کجا که بخواهید به جای نام کامل استفاده کنید :

myAlias::Sample s;

نام مستعار برای یک Type

شما همچنین می‌توانید از نام مستعار برای تعریف Type ها نیز استفاده کنید. برای این منظور باید از کلمه کلیدی typedef به صورت زیر استفاده کنید :

typedef my::name::MyClass MyType;

در اینجا ما به جای my::name::MyClass از نام مستعار MyType استفاده کردیم. حال هر کجا که بخواهیم می‌توانیم از MyType یک نمونه تعریف کنیم :

MyType t;

از Typedef نه تنها برای Type های از قبل تعریف شده، بلکه برای تعریف یک Type جدید مانند class ، struct ، union یا enum نیز می‌توان استفاده کرد.

typedef struct { int len; } Length;
Length a, b, c;

ساخت نام مستعار با استفاده از Typedef خیلی توصیه نمی‌شود و باعث ایجاد ابهام در کدها می‌شود. گرچه اگر از نام‌های مستعار به درستی استفاده شود، می‌تواند از طولانی شدن و تداخل نام‌ها در کد جلوگیری کند.

تفاوت Include و using

include کردن یک فایل header به این معنی است که می‌خواهیم قبل از عملیات کامپایل، محتویات این فایل در مکانی که آن را include کردیم کپی شود. در حالی که using فقط نام‌ها را از یک scope به scope فعلی می‌آورد و تاثیری بر کامپایلر ندارد. به همین دلیل است که وقتی ما برای مثال iostream را include می‌کنیم، برای استفاده از فضای نام std که در iostream قرار دارد باید آن را using کنیم :

// Include input/output prototypes
#include <iostream>
 
// Import standard library namespace to global scope
using namespace std;

نکته: برای include کردن فایل‌های header از قبل تعریف شده، از <#include> و برای فایل‌های تعریف شده توسط برنامه نویس، از “#include” استفاده می‌شود.