حل شد........
Printable View
حل شد........
پس در این صورت شما جایی رو که نفهمیدین بگین تا من توضیح بدم . چون اگه از من بخواین که باز در مورد h. و cpp. توضیح بدم همون مطالب قبلی رو تکرار می کنم . چرا نفهمیدین ؟ چیشو نفهمیدین ؟ نکته خاصی نداره که !!
فکر کنم منظورشون اینه که اسم توابع و نوع پارامتراشون و ... تو فایل h. میریزیننقل قول:
بازم من نفهمیدم...
بدنه اصلی توابع و کلاسها که همون کدهاشون میشه رو هم تو فایل cpp. میریزین
البته اینارو دوستمون هم گفتم حالا ما یکم جمله بندیشو تغییر دادیم شاید بفهمید.
---------------------------
جناب sin2x=2sinxcosx به کارتون ادامه بدین ما هم داریم با اینا پیش میریم ببینیم آخر این ++C رو یاد می گیریم یا نه
راستی یکی از مثالاتون شبیه یه سوال امتحانیمون بود:19: ، نکنه طراح سوالای ما بودین:46:
جمله بندیتون هم خیلی باحاله، این جملتون رو میگم:31: :31:
نقل قول:
تو ارث بري هم ميگيم فلان يه فلان است .
سوال من اینجاست که چرا این کار میکنن؟نقل قول:
فکر کنم منظورشون اینه که اسم توابع و نوع پارامتراشون و ... تو فایل h. میریزین
بدنه اصلی توابع و کلاسها که همون کدهاشون میشه رو هم تو فایل cpp. میریزین
البته اینارو دوستمون هم گفتم حالا ما یکم جمله بندیشو تغییر دادیم شاید بفهمید.
---------------------------
با عرض سلام و تشکر .نقل قول:
منظورم از فلان یه فلان است این بود که مثلا اگه دو تا کلاس به نام های base و derived داشته باشیم و کلاس derived از کلاس base به ارث رسیده باشد ، در این صورت میگیم : derived یه base است .
ولی تو Composition میگیم : فلان یه فلان دارد .:20:
در این مورد هم توضیح دادم :نقل قول:
سوال من اینجاست که چرا این کار میکنن؟
من هم ان شاءالله پست بعدیم راجع به Operator Overloading خواهد بود . دارم الان آماده می کنم .نقل قول:
2- اتفاقا اين کلاس رو به دو فايل h. و cpp. تبديل مي کنيم تا مفهوم شيء گرايي حفظ بشه . به کاربري که قصد استفاده از اين کلاس ما رو داره فقط فايل هدر داده ميشه که فقط اينو بدونه که اين کلاس ما چه توابعي دارن و چه آرگومان هايي مي گيرن . با ارائه توضيحات در فايل هدر توسط برنامه نويس کلاس ، ميشه بهتر کاربر برنامه نويس تابع main رو در جهت استفاده از کلاس راهنمايي کرد . فايل کامپايل شده فايل cpp کلاس هم به مشتري يا همون استفاده کننده از کلاس داده ميشه که بتونه به فايل h. پيوند بزنه . Source فايل cpp نبايد در دسترس مشتري قرار بگيره و اين همون مفهوم کپسوله سازي و مهندسي نرم افزار و تکنولوژي شيء گراييه که مشتري نبايد از چگونگي پياده سازي توابع اطلاع داشته باشه . فقط کافيه بدونه که چه توابعي وجود دارن و اين توابع چيکار مي کنن . ديگه لازم نيست بدونه که چه الگوريتمي براي انجام اين کار پياده سازي شده .
در مورد اين هم که هر کس فايل هدر رو داشته باشه مي تونه فايل cpp رو از روي اون بنويسه ، بايد بگم که خوب بنويسه . چه اشکالي داره . مهم اينه که به پياده سازي مدنظر ما لطمه وارد نشه .
خوب حالا پس از مدت ها : سربارگذاری عملگر یا Operator Overloading
سربارگذاری همون طوری که از اسمش مشخصه یعنی گذاشتن بار اضافی . همین کلمه اضافی و درک اون تو مفهوم سربارگذاری خیلی مهمه . :20: بعدا میگم یعنی چی . پس سربارگذاری عملگر میشه گذاشتن بار اضافی روی عملگر .
فرض کنین ما یه کلاس تعریف کردیم به اسم HugeInteger . این کلاس ، کلاس معروفی هست که کاربر می تونه ایجاد کنه تا محدودیت های نوع داده int رو جبران کنه . نوع داده int فکر کنم حداکثر تا 12 رقم پشتیبانی می کنه . با پیاده سازی کلاس HugeInteger میشه کلاس ( یا نوع داده جدیدی ) ایجاد کرد که تا بی نهایت رقم پشتیبانی کنه .
خوب فرض کنین ما برای این کلاسمون یه تابع عضو تعریف کردیم که عمل جمع رو بین دو تا شیء HugeInteger انجام میده . با فراخوانی این تابع به صورت مثلا زیر می تونیم این کارو انجام بدیم :
یعنی به تابع sum موجود تو کلاسمون ، دو تا شیء HugeInteger به نام های h1 و h2 می فرستیم و این تابع این دو تا رو جمع می کنه و نتیجه رو در قالب یه شیء HugeInteger دیگه به ما برمی گردونه .کد:sum ( h1, h2 );
ولی وقتی می خوایم دو تا int رو با هم جمع کنیم چیکار می کنیم ؟ خیلی راحت می نویسیم :
ولی اگه بخوایم از عملگر + برای یه نوع داده ای ، غیر از انواع داده اصلی ( int, double, float, long ) مثلا برای کلاس HugeInteger استفاده کنیم از جانب Compiler اروری با این مضمون دریافت می کنیم :کد:a + b;
ولی ما دوست داریم از این عملگر برای کلاس خودمون بین دو تا شیء HugeInteger استفاده کنیم . برای این کار باید ما عملگر + رو برای کلاسمون سربارگذاری کنیم و این مفهوم سربارگذاری عملگر هست .کد:binary '+' : 'HugeInteger' does not define this operator or a conversion to a type acceptable to the predefined operator
چند نکته در مورد سربارگذاری عملگر ها :
1- با سربارگذاری نمی توان عملگرهای جدید ایجاد کرد . فقط عملگرهای موجود را می توان سربارگذاری کرد .
2- با سربارگذاری یک عملگر ، عملگر مربوطه علاوه بر اینکه بین انواع داده ای اصلی مثل int تعریف شده است ، برای کلاس موردنظر ما هم تعریف شده خواهد بود . یعنی با سربارگذاری یک عملگر برای یک کلاس ، آن عملگر باز هم به وظیفه های قبلی خود در مورد انواع داده ای دیگر آشنا است . ( همون مفهوم کلمه بار اضافی اینجا بود . )
3- چهار عملگر وجود دارد که نمی توان آن ها را سربارگذاری کرد :
بقیه عملگر ها قابل سربارگذاری هستند . حتی عملگرهای new و delete .کد:. .* :: ?:
4- دو عملگر زیر تنها عملگرهایی هستند که قادرند بدون سربارگذاری با هر نوع داده ای بکار روند :
کد:& ,
مرسی.
ولی کاش 1 خط کد هم می نوشتید که چجوری باید سربارگذاری کرد!
آخه این فقط شد تعریفش!
منبع : Prentice.Hall.C.plus.plus.How.to.Program.5th.Editi on.Jan.2005.INTERNAL
کد:
1 // Fig. 11.4: PhoneNumber.cpp
کد:
1 // Fig. 11.3: PhoneNumber.h 2 // PhoneNumber class definition 3 #ifndef PHONENUMBER_H 4 #define PHONENUMBER_H 5 6 #include <iostream> 7 using std::ostream; 8 using std::istream; 9 10 #include <string> 11 using std::string; 12 13 class PhoneNumber 14 { 15 friend ostream &operator<<( ostream &, const PhoneNumber & ); 16 friend istream &operator>>( istream &, PhoneNumber & ); 17 private: 18 string areaCode; // 3-digit area code 19 string exchange; // 3-digit exchange 20 string line; // 4-digit line 21 }; // end class PhoneNumber 22 23 #endif
2 // Overloaded stream insertion and stream extraction operators
3 // for class PhoneNumber.
4 #include <iomanip>
5 using std::setw;
6
7 #include "PhoneNumber.h"
8
9 // overloaded stream insertion operator; cannot be
10 // a member function if we would like to invoke it with
11 // cout << somePhoneNumber;
12 ostream &operator<<( ostream &output, const PhoneNumber &number )
13 {
14 output << "(" << number.areaCode << ") "
15 << number.exchange << "-" << number.line;
16 return output; // enables cout << a << b << c;
17 } // end function operator<<
18
19 // overloaded stream extraction operator; cannot be
20 // a member function if we would like to invoke it with
21 // cin >> somePhoneNumber;
22 istream &operator>>( istream &input, PhoneNumber &number )
23 {
24 input.ignore(); // skip (
25 input >> setw( 3 ) >> number.areaCode; // input area code
26 input.ignore( 2 ); // skip ) and space
27 input >> setw( 3 ) >> number.exchange; // input exchange
28 input.ignore(); // skip dash (-)
29 input >> setw( 4 ) >> number.line; // input line
30 return input; // enables cin >> a >> b >> c;
31 } // end function operator>>
کد:1 // Fig. 11.5: fig11_05.cpp
2 // Demonstrating class PhoneNumber's overloaded stream insertion
3 // and stream extraction operators.
4 #include <iostream>
5 using std::cout;
6 using std::cin;
7 using std::endl;
8
9 #include "PhoneNumber.h"
10
11 int main()
12 {
13 PhoneNumber phone; // create object phone
14
15 cout << "Enter phone number in the form (123) 456-7890:" << endl;
16
17 // cin >> phone invokes operator>> by implicitly issuing
18 // the global function call operator>>( cin, phone )
19 cin >> phone;
20
21 cout << "The phone number entered was: ";
22
23 // cout << phone invokes operator<< by implicitly issuing
24 // the global function call operator<<( cout, phone )
25 cout << phone << endl;
26 return 0;
27 } // end main
Enter phone number in the form (123) 456-7890:
(800) 555-1212
The phone number entered was: (800) 555-1212
Overloading Unary OperatorsOverloading Binary Operatorsکد:
class String { public: bool operator!() const; ... }; // end class String
bool operator!( const String & );
Overloading ++ and --کد:class String public: bool operator<( const String & ) const; ... }; // end class String
کد:Overloading the Prefix Increment Operator
d1.operator++()
Suppose, for example, that we want to add 1 to the day in Date object d1. When the compiler sees the preincrementing expression ++d1, the compiler generates the member-function call
Date &operator++();
The prototype for this operator function would be
operator++( d1 )
If the prefix increment operator is implemented as a global function, then, when the compiler sees the expression ++d1, the compiler generates the function call
Date &operator++( Date & );
The prototype for this operator function would be declared in the Date class as
Overloading the Postfix Increment Operator
d1.operator++( 0 )
Overloading the postfix increment operator presents a challenge, because the compiler must be able to distinguish between the signatures of the overloaded prefix and postfix increment operator functions. The convention that has been adopted in C++ is that, when the compiler sees the postincrementing expression d1++, it generates the member-function call
Date operator++( int )
The prototype for this function is
operator++( d1, 0 )
The argument 0 is strictly a "dummy value" that enables the compiler to distinguish between the prefix and postfix increment operator functions.
If the postfix increment is implemented as a global function, then, when the compiler sees the expression d1++, the compiler generates the function call
Date operator++( Date &, int );
The prototype for this function would be
Once again, the 0 argument is used by the compiler to distinguish between the prefix and postfix increment operators implemented as global functions. Note that the postfix increment operator returns Date objects by value, whereas the prefix increment operator returns Date objects by reference, because the postfix increment operator typically returns a temporary object that contains the original value of the object before the increment occurred. C++ treats such objects as rvalues, which cannot be used on the left side of an assignment. The prefix increment operator returns the actual incremented object with its new value. Such an object can be used as an lvalue in a continuing expression.
ممنون ها آبجی، ولی 1 کم نا مفهوم بود!
آخه زبان شیرین پارسی رو ول کردید، به زبان خارجه (:27:) نوشتید، اون هم با نظم کم و ...
تقریباً فهمیدم مطلب چیه.
ولی اگر فارسی توضیح بدید، حداقل برای تازه کار ها بهتره.
ممنون از لطفتون