PDA

View Full Version : سوال: سازنده پیش فرض خصوصی



Saeed_m_Farid
دوشنبه 23 دی 1387, 16:48 عصر
با سلام
میخواستم ببینم اگه سازنده پیش فرض یه کلاس به صورت خصوصی تعریف بشه چه اتفاقی میافته؟
یعنی یه چیزی مثل کلاس پایین اگه بنویسم :


class MyAccount{
private:
float balance;
/*
.
.
.
*/

// -- Default Constructor
MyAccount(){/*...*/}
public:
// -- Set, and get Balance
void SetBalance(const float newBalance);
float GetBalance() const;

/*
.
.
.
*/

// -- Print Client information
void Print() const;
};
خودم که فکر میکنم همچین کلاسی؛ مثل کلاسهای abstract جاوا یا #C میشه و نمیشه مستقیم ازشون instance درست کرد، ضمنا به نظرتون کلاسی که از این کلاس ارث ببره میتونه سازنده رو override کنه یا virtual تعریف کردش(به شرطیکه من والد رو virtual تعریف کنم)

ممنون میشم اگه نظرتون رو بگید.
با تشکر

sasan_vm
دوشنبه 23 دی 1387, 16:53 عصر
سلام
از این کلاس هیج object ای ایجاد نمیشه و حتی در کلاس فرزند ، چون constructor را نمی توانید بصورت
virtual معرفی کنید.

Saeed_m_Farid
دوشنبه 23 دی 1387, 17:19 عصر
سلام
از این کلاس هیج object ای ایجاد نمیشه و حتی در کلاس فرزند ، چون constructor را نمی توانید بصورت
virtual معرفی کنید.
یعنی چی؟ یعنی این کلاس رو باید انداخت دور؟!
حتما دلیلی داره که همچین کلاسهایی تعریف میشن، قرار نیست من تو کلاس فرزند آبجکت درست کنم فقط میخوام از این کلاس اعضاء public اش رو ارث ببرم، اصلا هم با سازنده تو کلاس فرزند کاری ندارم.
احتمال میدم این کلاس واسه همین اینطوری طراحی شده که من نتونم با سازنده اش کاری داشته باشم.

sasan_vm
دوشنبه 23 دی 1387, 18:08 عصر
یعنی چی؟ یعنی این کلاس رو باید انداخت دور؟!
حتما دلیلی داره که همچین کلاسهایی تعریف میشن،
احتمال میدم این کلاس واسه همین اینطوری طراحی شده که من نتونم با سازنده اش کاری داشته باشم.

تا به حال همچین تعریفی ندیدم البته بغیر از کد شما :لبخند:، حتما می دونید وقتی یک شیء
ایجاد می شود ابتدا constructor کلاس پدر اجرا می شود.



قرار نیست من تو کلاس فرزند آبجکت درست کنم فقط میخوام از این کلاس اعضاء public اش رو ارث ببرم،

اگر قرار نیست از این کلاس یا کلاسهای فرزند شیء ایجاد بشه پس اون توابع public کجا باید استفاده بشه :گیج:

Mehdi Asgari
دوشنبه 23 دی 1387, 20:09 عصر
از سازندۀ private برای مواقعی استفاده میشه که نمیخوایم کسی بتونه یه instance از کلاسمون ایجاد کنه
مثال: الگوی Singleton (http://en.wikipedia.org/wiki/Singleton_pattern)

Saeed_m_Farid
دوشنبه 23 دی 1387, 22:25 عصر
تا به حال همچین تعریفی ندیدم البته بغیر از کد شما :لبخند:، حتما می دونید وقتی یک شیء ایجاد می شود ابتدا constructor کلاس پدر اجرا می شود.
دوست عزيز اين كلاسيه كه از نظر كامپايلر مشكلي نداره و خوب واسم عجيبه كه سازنده كلاس والد به فرزند به ارث نرسه! و همونطور كه آقاي mehdi311ggg گفتن هيچ كسي ازش instance (شيء) درست نميكنه چون اين امكان وجود نداره و فقط ميشه ازش ارث برد.
جسارتا اگه يكمي دقت ميكردين سوال بنده اين بود : آيا ميشه اين تعريف رو معادل کلاسهای abstract جاوا یا #C دونست يا نه؟
من تو پست قبلي هم گفتم نميخواهيم يك شيء از اين كلاس ايجاد كنيم! قصد بنده اينه كه از كلاس پدر يه كلاس inherited ايجاد بشه و اين دقيقا معادل شيء ايجاد كردن نيست؛

Mehdi Asgari
دوشنبه 23 دی 1387, 23:37 عصر
ضمنا اين كلاس يه كلاس استاندارد هست كه همونطور كه آقاي mehdi311ggg گفتن هيچ كسي ازش instance (شيء) درست نميكنه و فقط ميشه ازش ارث برد
من نگفتم قابل ارث بردن هست. در سی پلاس پلاس ایجاد یک شی از یک کلاس ، باعث فراخوانی سازندۀ اون کلاس و کلاس های رده بالاتر (پدر) میشه.

آيا اين تعريف معادل کلاسهای abstract جاوا یا #C هست
جاوا رو نمی دونم ولی سی شارپ نه. اصلا ربطی ندارن. abstract برای ایجاد کلاس هایی هست که قراره فقط به عنوان یه کلاس پدر باشن (بدون پیاده سازی) و پیاده سازی رو به عهدۀ کلاس های فرزند میذارن (نمونه: System.IO.Stream ) و ازشون نمیشه یک instance درست کرد.

پ ن: دوستان لطفا از شکلک ها درست استفاده کنید؛ بعضی وقت ها مشکل ساز میشه. ندانستن یا سوال پرسیدن عیب نیست. اگه کسی همه چیز رو می دونست دیگه فعالیت کردنش در این فروم بی مورد می بود.

Saeed_m_Farid
سه شنبه 24 دی 1387, 00:11 صبح
از سازندۀ private برای مواقعی استفاده میشه که نمیخوایم کسی بتونه یه instance از کلاسمون ایجاد کنهو

abstract برای ایجاد کلاس هایی هست که قراره فقط به عنوان یه کلاس پدر باشن (بدون پیاده سازی) و پیاده سازی رو به عهدۀ کلاس های فرزند میذارن (نمونه: System.IO.Stream ) و ازشون نمیشه یک instance درست کرد.فكر ميكنم اين دو تا جمله خيلي شبيه هم هستن؛ ميشه تفاوتشون رو بگين؟
(نميدونم چرا ميگين اصلا ربطي ندارن، بنظر من عين هم هستند؛ البته فرض كنيد من getter و setter اعضاء ديگه رو كه واسه مثال آوردم حذف كنم.)

خودم :

همونطور كه آقاي mehdi311ggg گفتن هيچ كسي ازش instance (شيء) درست نميكنه و فقط ميشه ازش ارث برد منظورم اين بود كه نميشه ازشون instance درست كرد مگه شما هم همين رو نگفتين؟ من هم در اولين پست به اين مورد اشاره كرده بودم. ضمنا اگه نميشه ازش instance درست كرد و قابل ارث بردن هم نيست كلاس موردنظر يه كلاس كاملا بي استفاده ميشه!

Nima_NF
سه شنبه 24 دی 1387, 00:57 صبح
منظورم اين بود كه نميشه ازشون instance درست كرد مگه شما هم همين رو نگفتين؟ من هم در اولين پست به اين مورد اشاره كرده بودم. ضمنا اگه نميشه ازش instance درست كرد و قابل ارث بردن هم نيست كه بايد كلاس رو انداخت دور؟!این نوع از کلاس ها کلاس هایی هستند که نمی توان از آن بیش از یک نمونه ساخت و همین طور نمی توان از آن ارث برد. (مگر با ایجاد متدی برای این کار توسط خودمان)

کجا کاربرد دارد:
1- از آن در مواقعی استفاده می کنیم که می دانیم کلاس ما دارای متدهای قابل استفاده نیست (می خواهیم از سایر محتوای دسته بندی شده در کلاس استفاده کنیم).

2- یا کلا متدها و متغیرهای ما به صورت static (و البته public) تعریف شده اند. در این صورت می توان از آن ها استفاده کرد.

3- فقط وقتی که ما از طریق یک متد خودمان دستی نمونه ای از کلاس بسازیم، اجازه نمونه سازی داده شود.
نکته: هدف از ایجاد این کلاس ها همین هست که بیش از یک نمونه ایجاد نشود (Singleton)، البته با ایجاد یک متد static می توانیم بگوییم اجازه ساخت یک نمونه دیگر نیز بدهد:




#include <iostream>
#include <conio.h>

using namespace std;

class MainClass
{
private:
MainClass() { cout << "Main class\n"; }
public:
static MainClass* NewInst();
static void Function1() { cout << "Function1\n"; }
};

MainClass* MainClass::NewInst()
{
MainClass* pMClass = new MainClass;

return pMClass;
}

int main()
{

MainClass::Function1();

MainClass* pNewClass = MainClass::NewInst();

_getch();
return 0;
}

برنامه فوق را اجرا کنید تا نتیجه را ببینید، وقتی تابع Function1 فراخوانی شد، در خط بعدی آن بعد از ساخت یک نمونه جدید، سازنده کلاس نیز فراخوانی می شود.

Nima_NF
سه شنبه 24 دی 1387, 01:08 صبح
ضمنا بعضی از کتابخانه ها در #C مانند کتابخانه Math به همین شکل طراحی شده اند و برای فراخوانی باید نوشت : ()Math.Abs
در ++C باید نوشت : ()Math::Abs

Mehdi Asgari
سه شنبه 24 دی 1387, 01:19 صبح
نیما جان ، static class ها در سی شارپ با پترن Singleton تفاوت هایی دارن ، از جمله:
کلاس های استاتیک فقط می تونن حاوی اعضای static باشن
و کلاس Math یک static class هست

Nima_NF
سه شنبه 24 دی 1387, 02:32 صبح
نیما جان ، static class ها در سی شارپ با پترن Singleton تفاوت هایی دارن ، از جمله:
کلاس های استاتیک فقط می تونن حاوی اعضای static باشن
و کلاس Math یک static class هست
منظورم استفاده از سازنده خصوصی در NET. بود نه لزوما static class.

که بله اگر تمامی متدها static باشد در #C کل کلاس را static class تعریف می کنیم.



Private constructors are used to prevent the creation of instances of a class when there are no instance fields or methods, such as the Math class, or when a method is called to obtain an instance of a class. If all the methods in the class are static, consider making the entire class static.

Marjan_Bala
شنبه 23 آبان 1388, 17:47 عصر
جناب Nima_NF ببخشید میشه در مورد کدی که گذاشتید یه کم توضیح بدین؟
تابع Function1 چیکار میکنه؟
بعد اینکه از این نمونه ای که ساختیم چجوری باید استفاده کرد ، زیاد از این اشاره گرا سر در نمیارم.

Marjan_Bala
یک شنبه 24 آبان 1388, 16:19 عصر
دوستان کسی از این کد سر در نمیاره ، لینک درست حسابی هست که مفهوم کلاسهای Singleton رو قشنگ توضیح داده باشه؟