کلاس دوست

**کلاس دوست** در سی++، می‌تواند به اعضای خصوصی و حفاظت شدهٔ کلاسی که در آن به عنوان دوست معرفی شده، دسترسی داشته باشد. وضعیت دوستی به ارث نمی‌رود. هر رابطه دوستی باید تصریح شود. کلاس‌های دوست اگر به درستی استفاده شوند، در بهبود کپسوله‌سازی مؤثرند.

## تعریف
کلاس‌ها در قسمت تعریف آن کلاسی که در آن به کلاس‌های دیگر دسترسی پیدا می‌کنند، دوست تعریف می‌شوند. این از اینکه یک کلاس اجازه دسترسی به اعضای حفاظت شدهٔ کلاس دیگر بدهد، مانع می‌شود که در واقع اعمال قانون کپسوله سازی صورت می‌گیرد. کلاس دوست مانند خود  کلاس اصلی به اعضای آ«دسترسی دارد و فارغ از تعریف دوستی، در قسمت public و private و protected تعریف کلاس می‌آید. دوستی با کلمه کلیدی friend مشخص می‌شود:

```cpp
friend class ClassName;
```


### مثال


```cpp
# include <iostream>

class B
{
    // B declares A as a friend...
    friend class A;

private:
    void privatePrint()
    {
        std::cout <<"hello, world" <<std::endl;
    }
};

class A
{
public:
    A()
    {
        B b;
        //... and A now has access to B's private members
        b.privatePrint();
    }
};

int main()
{
    A a;
    return 0;
}
```


## مزایای استفاده از کلاس دوست
قابلیت‌های اضافه تری فراهم می‌کند که خارج از کلاس نگهداری می‌شود.
داده‌های جدیدی برای توابع فراهم می‌کند که در حالت عادی توسط کلاس استفاده نمی‌شود.
دادن دسترسی مستقیم به اعضای خصوصی و حفاظت شده به یک محدودهٔ مشخص شدهٔ خارجی، روشی برای کاهش پیچیدگی الگوریتم‌ها بیان می‌کند بدون این که اعضا را بیش از اندازه مورد نیاز قابل دسترسی کند.

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

## حوزه
اسم کلاسی که در تعریف کلاس دوست معرفی شده، حوزه‌اش جزء دادنِ دسترسی ِ دوستی ِ کلاس نیست و عضو کلاسی که دسترسی می‌دهد، نمی‌باشد. اگر اسم کلاس دوست، پیش از تعریف کلاس دوست بیاید، در این صورت کامپایلر به دنبال کلاسی با اسمی مطابق با اسم ِ کلاس ِ دوست ِ آمده در حوزهٔ تعریف ِ دوست می‌گردد. اگر اسمِ کلاسی که این کلاس در داخلش است، باشد، در این صورت کلاسی (که در داخل است)، دوست ِ کلاس بالایی می‌باشد.

### مثال

```cpp
class X{
      class Y{
           friend class Z;
      }
 }
```


معادل است با:


```cpp
class Z;
 class X{
      class Y{
           friend class Z;
      };
 };
```


## ویژگی‌ها
* **رابطه دوستی دو طرفه نیست**: اگر کلاس A، دوست کلاس B باشد، در این صورت کلاس B، دوست کلاس A نمی‌باشد.
* **رابطه تعدی وجود ندارد**: اگر کلاس A دوست کلاس B باشد و کلاس B دوست کلاس C باشد، کلاس A به خودی خود دوست کلاس C نیست.
* **رابطه دوستی به ارث نمی‌رود**: دوست کلاس پدر به خودی خود دوست کلاس مشتق شده نمی‌شود و بالعکس اگر کلاس پدر دوست کلاس دیگری باشد، کلاس مشتق شده، به خودیِ خود، دوست آن کلاس نخواهد شد.
* **دسترسی مربوط به دوستی به ارث می‌رود**: دوست کلاس مشتق شده می‌تواند به اعضای محدود شدهٔ کلاس مشتق شده که از کلاس پدر به ارث رفته‌اند، دسترسی پیدا کنند. لازم به ذکر است با وجود این که دوست کلاس مشتق شده  فقط به اعضای به ارث رفته از پدری که خودِ کلاسِ مشتق شده به آن دسترسی دارد، دسترسی خواهد داشت. *مثال*: در صورتی که کلاس مشتق شده به صورت عمومی از پدر به ارث رود، کلاس مشتق شده تنها به اعضای حفاظت شده (و عمومی) ی پدر، دسترسی پیدا می‌کند نه اعضای خصوصی. این مطلب برای کلاس دوست نیز صادق است.

## دوستی و کپسوله سازی
گفته می‌شود که کلاس‌های دوست رابطه کپسوله سازی را نقض می‌کنند چرا که به داخل کلاس اعلام شده دسترسی داشته باشد. دوست به یک کلاس اجازه می‌دهد به وسلیه مخفی کردن جزئیات می‌تواند با هر چیزی اما دوستانی از کلاس لازم بشود.
گفته می‌شود که کلاس‌های دوست می‌توانند کپسوله سازی را بهبود بخشند. از آنجا که به نویسنده کتابخانه‌ها اجازه می‌دهد تا یک رابط، بنویسد که نیازی به بر ملا شدن آن نیست تا از آن برای ارجاع داخلی شود.

## منابع

## پیوند به بیرون
* http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr043.htm
* http://www.cplusplus.com/doc/tutorial/inheritance/

رده:کلاس (برنامه‌نویسی)